roa.py 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. from __future__ import annotations
  2. import dataclasses
  3. import typing
  4. import cache
  5. import roi
  6. def main() -> None:
  7. sankey: typing.Mapping[str, SankeyMat] = cache.get('https://benten.space/sankey_data.json')
  8. raw_prices: list[roi.RawPrice] = cache.get('https://refined-prun.github.io/refined-prices/all.json')
  9. prices: dict[str, roi.Price] = {
  10. p['MaterialTicker']: roi.Price(p['VWAP7D'], p['AverageTraded7D'], p['VWAP30D']) for p in raw_prices
  11. if p['ExchangeCode'] == 'IC1'
  12. }
  13. profits: list[Profit] = []
  14. for mat, sankey_data in sankey.items():
  15. price = prices[mat]
  16. if price.vwap_7d is None:
  17. continue
  18. assert price.average_traded_7d is not None
  19. profits.append(Profit(mat, price.vwap_7d / area_cost(mat, sankey_data), price.average_traded_7d))
  20. profits.sort(reverse=True)
  21. for profit in profits:
  22. print(f'{profit.material:4} {profit.per_area:5.2f} {profit.traded:6.2f}')
  23. def area_cost(mat: str, sankey_data: SankeyMat) -> float:
  24. return sum(link['value'] for link in sankey_data['links'] if link['source'] == mat)
  25. class SankeyMat(typing.TypedDict):
  26. links: typing.Sequence[SankeyLink]
  27. class SankeyLink(typing.TypedDict):
  28. source: str
  29. value: float
  30. @dataclasses.dataclass(eq=False, frozen=True, slots=True)
  31. class Profit:
  32. material: str
  33. per_area: float
  34. traded: float
  35. def __lt__(self, other: Profit) -> bool:
  36. return self.per_area < other.per_area
  37. if __name__ == '__main__':
  38. main()