sell.py 2.7 KB

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