sell.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. from __future__ import annotations
  2. import collections
  3. import dataclasses
  4. import typing
  5. import cache
  6. from config import config
  7. import market
  8. if typing.TYPE_CHECKING:
  9. import supply
  10. def main() -> None:
  11. raw_prices: typing.Mapping[str, market.RawPrice] = {p['MaterialTicker']: p
  12. for p in cache.get('https://refined-prun.github.io/refined-prices/all.json') if p['ExchangeCode'] == 'IC1'}
  13. planets: typing.Sequence[supply.FIOBurn] = cache.get('https://rest.fnar.net/fioweb/burn/user/' + config.username,
  14. headers={'Authorization': config.fio_api_key})
  15. producing = frozenset(mat['MaterialTicker'] for planet in planets for mat in planet['OrderProduction']
  16. if mat['MaterialTicker'] not in (c['MaterialTicker'] for c in planet['OrderConsumption']))
  17. materials: list[Material] = []
  18. for mat in producing:
  19. price = raw_prices[mat]
  20. if price['Bid'] is None or price['Ask'] is None:
  21. print(mat, 'has no bid/ask')
  22. continue
  23. spread = (price['Ask'] - price['Bid']) / price['Ask']
  24. chart_analysis = market.analyze_price_chart(mat + '.IC1', (price['Bid'] + price['Ask']) / 2)
  25. ask_fill_ratio = chart_analysis.asks_filled / (chart_analysis.bids_filled + chart_analysis.asks_filled)
  26. materials.append(Material(mat, spread=spread, bid=price['Bid'], ask=price['Ask'], score=spread * ask_fill_ratio))
  27. materials.sort()
  28. all_orders: typing.Sequence[market.ExchangeOrder] = cache.get('https://rest.fnar.net/cxos/' + config.username,
  29. headers={'Authorization': config.fio_api_key})
  30. orders: dict[str, int] = collections.defaultdict(int)
  31. for order in all_orders:
  32. if order['OrderType'] != 'SELLING' or order['Status'] == 'FILLED' or order['ExchangeCode'] != 'IC1':
  33. continue
  34. orders[order['MaterialTicker']] += order['Amount']
  35. print(f'{"mat":^4} spread asks instant cash loss')
  36. for m in materials:
  37. print(f'{m.ticker:4} {m.spread*100:5.1f}%', end='')
  38. if asks := orders.pop(m.ticker, None):
  39. print(f' {asks:5} {asks * m.bid:13} {asks * (m.ask - m.bid):5}')
  40. else:
  41. print()
  42. print('\nother listings:')
  43. for mat, asks in orders.items():
  44. print(f'{mat:4} {asks:5}')
  45. @dataclasses.dataclass(eq=False, slots=True)
  46. class Material:
  47. ticker: str
  48. spread: float
  49. bid: float
  50. ask: float
  51. score: float
  52. def __lt__(self, o) -> bool:
  53. return self.score < o.score
  54. if __name__ == '__main__':
  55. main()