sell.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. from __future__ import annotations
  2. import collections
  3. import json
  4. import math
  5. import sys
  6. import typing
  7. import cache
  8. from config import config
  9. import market
  10. import supply
  11. if typing.TYPE_CHECKING:
  12. import supply
  13. def main() -> None:
  14. (ship,) = sys.argv[1:]
  15. ship_inventory = get_ship_storage(ship)
  16. warehouse_inventory = supply.warehouse_inventory()
  17. raw_prices: typing.Mapping[str, market.RawPrice] = {p['MaterialTicker']: p
  18. for p in cache.get('https://refined-prun.github.io/refined-prices/all.json') if p['ExchangeCode'] == 'IC1'}
  19. consumption = get_consumption()
  20. to_sell: dict[str, int] = {}
  21. price_limits: dict[str, int] = {}
  22. for item in ship_inventory:
  23. ticker = item['MaterialTicker']
  24. print(f'{item["MaterialAmount"]:5} {ticker:3}:', end=' ')
  25. have = item['MaterialAmount'] + warehouse_inventory.get(ticker, 0)
  26. need = math.ceil(consumption.get(ticker, 0) * 14)
  27. sell = min(have - need, item['MaterialAmount'])
  28. keep = item['MaterialAmount'] - sell
  29. if sell > 0:
  30. print('sell', sell, end=' ')
  31. to_sell[ticker] = sell
  32. ask = raw_prices[ticker]['Ask']
  33. if ask is None:
  34. print('(NO ASK)', end=' ')
  35. else:
  36. epsilon = 10 ** (int(math.log10(ask)) - 2)
  37. price_limits[ticker] = ask - 2 * epsilon
  38. if keep > 0:
  39. print('keep', keep, end= ' ')
  40. print()
  41. print('\n' + json.dumps({
  42. 'global': {'name': 'sell ' + ship},
  43. 'groups': [{'type': 'Manual', 'name': 'A1', 'materials': to_sell}],
  44. 'actions': [
  45. {'name': 'sell', 'type': 'CX Sell', 'group': 'A1', 'exchange': 'IC1', 'origin': ship + ' Cargo',
  46. 'priceLimits': price_limits, 'sellPartial': True, 'allowUnfilled': True},
  47. ],
  48. }))
  49. def get_ship_storage(ship_name: str) -> typing.Sequence[market.StorageItem]:
  50. ship_name = ship_name.casefold()
  51. stores: typing.Sequence[market.Storage] = cache.get('https://rest.fnar.net/storage/' + config.username,
  52. headers={'Authorization': config.fio_api_key})
  53. for store in stores:
  54. if store['Type'] == 'SHIP_STORE' and store['Name'].casefold() == ship_name:
  55. return store['StorageItems']
  56. raise Exception(f'ship storage {ship_name} not found')
  57. def get_consumption() -> typing.Mapping[str, float]:
  58. '''get consumption on planets that consume each mat'''
  59. planets = [supply.Planet(fio_burn) for fio_burn in cache.get('https://rest.fnar.net/fioweb/burn/user/' + config.username,
  60. headers={'Authorization': config.fio_api_key})]
  61. consumption: dict[str, float] = collections.defaultdict(float)
  62. for planet in planets:
  63. supply_config = config.supply_config(planet.name)
  64. for mat, amount in planet.net_consumption.items():
  65. if mat not in supply_config.ignore_materials and amount > 0:
  66. consumption[mat] += amount
  67. return consumption
  68. if __name__ == '__main__':
  69. main()