| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- from __future__ import annotations
- import dataclasses
- import sys
- import typing
- import cache
- import roi
- def main() -> None:
- from_cx, to_cx = sys.argv[1:]
- raw_prices: list[RawPrice] = cache.get('https://refined-prun.github.io/refined-prices/all.json')
- materials: dict[str, roi.Material] = {m['Ticker']: m for m in cache.get('https://api.prunplanner.org/data/materials')}
- bids: dict[str, float] = {}
- for price in raw_prices:
- if price['ExchangeCode'] != to_cx or price['Bid'] is None:
- continue
- assert price['Bid'] is not None
- bids[price['MaterialTicker']] = price['Bid']
- rates: list[FX] = []
- for price in raw_prices:
- if price['ExchangeCode'] != from_cx or price['Ask'] is None or (to_price := bids.get(price['MaterialTicker'])) is None:
- continue
- rate = (price['Ask'] - to_price) / to_price
- if rate < 0.01:
- rates.append(FX(price['MaterialTicker'], to_price, rate, price['AskCount']))
- rates.sort()
- print('mat rate per shipping max converted')
- for rate in rates:
- mat = materials[rate.ticker]
- if mat['Weight'] >= mat['Volume']:
- if (per_t := rate.to_price / mat['Weight']) < 1000:
- continue
- per_shipping = f'{per_t:9,.0f}/t '
- else:
- if (per_m3 := rate.to_price / mat['Volume']) < 1000:
- continue
- per_shipping = f'{per_m3:9,.0f}/m³'
- print(f'{rate.ticker:4} {rate.rate:8.5f} {per_shipping} {rate.depth * rate.to_price:12,.0f}')
- class RawPrice(typing.TypedDict):
- MaterialTicker: str
- ExchangeCode: str
- Ask: float | None
- Bid: float | None
- AskCount: int
- @dataclasses.dataclass(eq=False, frozen=True, slots=True)
- class FX:
- ticker: str
- to_price: float
- rate: float
- depth: int
- def __lt__(self, other: FX) -> bool:
- return self.rate < other.rate
- if __name__ == '__main__':
- main()
|