Browse Source

include existing inventory and bids

raylu 2 weeks ago
parent
commit
cfbb99cf8d
3 changed files with 45 additions and 17 deletions
  1. 35 5
      buy.py
  2. 8 1
      market.py
  3. 2 11
      supply.py

+ 35 - 5
buy.py

@@ -15,6 +15,7 @@ def main() -> None:
 	raw_prices: typing.Mapping[str, market.RawPrice] = {p['MaterialTicker']: p
 			for p in cache.get('https://refined-prun.github.io/refined-prices/all.json') if p['ExchangeCode'] == 'IC1'}
 
+	# what we need to buy
 	planets = [supply.Planet(fio_burn) for fio_burn in cache.get('https://rest.fnar.net/fioweb/burn/user/' + config.username,
 			headers={'Authorization': config.fio_api_key})]
 	buy: dict[str, int] = collections.defaultdict(int)
@@ -22,29 +23,58 @@ def main() -> None:
 		for mat, amount in planet.buy_for_target(7).items():
 			buy[mat] += amount
 
+	# what we have
+	warehouses: typing.Sequence[market.Warehouse] = cache.get('https://rest.fnar.net/sites/warehouses/' + config.username,
+			headers={'Authorization': config.fio_api_key})
+	for warehouse in warehouses:
+		if warehouse['LocationNaturalId'] == 'HRT':
+			storage: market.Storage = cache.get(f'https://rest.fnar.net/storage/{config.username}/{warehouse["StoreId"]}',
+				headers={'Authorization': config.fio_api_key})
+			assert storage['Type'] == 'WAREHOUSE_STORE'
+			warehouse = {item['MaterialTicker']: item['MaterialAmount'] for item in storage['StorageItems']}
+			break
+	else:
+		raise Exception("couldn't find HRT warehouse")
+
+	# what we already are bidding for
+	orders: typing.Sequence[market.ExchangeOrder] = cache.get('https://rest.fnar.net/cxos/' + config.username,
+			headers={'Authorization': config.fio_api_key})
+	bids = collections.defaultdict(int)
+	for order in orders:
+		if order['OrderType'] == 'SELLING' or order['Status'] == 'FILLED' or order['ExchangeCode'] != 'IC1':
+			continue
+		bids[order['MaterialTicker']] += order['Amount']
+
+	# what's left to buy
 	materials: list[Material] = []
 	for mat, amount in buy.items():
+		remaining = amount - bids[mat] - warehouse.get(mat, 0)
+		if remaining <= 0:
+			continue
 		price = raw_prices[mat]
 		if price['Bid'] is None or price['Ask'] is None:
 			print(mat, 'has no bid/ask')
 			continue
 		spread = price['Ask'] - price['Bid']
-		materials.append(Material(mat, amount=amount, spread=spread, total=spread * amount))
+		materials.append(Material(mat, amount=amount, bids=bids[mat], warehouse=warehouse.get(mat, 0),
+				spread=spread, savings=spread * remaining))
 	materials.sort(reverse=True)
 
-	print('mat  amount  total')
+	print('mat   want  bids  have   buy  savings')
 	for m in materials:
-		print(f'{m.ticker:4} {m.amount:>6} {m.total:6.0f}')
+		print(f'{m.ticker:4} {m.amount:>5} {m.bids:>5} {m.warehouse:>5} {m.amount - m.bids - m.warehouse:>5} {m.savings:8.0f}')
 
 @dataclasses.dataclass(eq=False, slots=True)
 class Material:
 	ticker: str
 	amount: int
+	bids: int
+	warehouse: int
 	spread: float
-	total: float
+	savings: float
 
 	def __lt__(self, o: Material) -> bool:
-		return self.total < o.total
+		return self.savings< o.savings
 
 
 if __name__ == '__main__':

+ 8 - 1
market.py

@@ -128,6 +128,7 @@ class ExchangeOrder(typing.TypedDict):
 	ExchangeCode: str
 	OrderType: typing.Literal['SELLING'] | typing.Literal['BUYING']
 	Status: typing.Literal['FILLED'] | typing.Literal['PARTIALLY_FILLED'] | typing.Literal['FILLED']
+	Amount: int
 	Limit: float
 
 class ExchangeSummary(typing.TypedDict):
@@ -141,9 +142,15 @@ class Warehouse(typing.TypedDict):
 	LocationNaturalId: str
 
 class Storage(typing.TypedDict):
-	StorageItems: typing.Sequence
+	Name: str
+	StorageItems: typing.Sequence[StorageItem]
 	WeightLoad: float
 	VolumeLoad: float
+	Type: typing.Literal['STORE'] | typing.Literal['WAREHOUSE_STORE'] | typing.Literal['FTL_FUEL_STORE'] | typing.Literal['STL_FUEL_STORE'] |  typing.Literal['SHIP_STORE']
+
+class StorageItem(typing.TypedDict):
+	MaterialTicker: str
+	MaterialAmount: int
 
 class RawPrice(typing.TypedDict):
 	FullTicker: str

+ 2 - 11
supply.py

@@ -26,7 +26,7 @@ def main() -> None:
 
 	planets = [Planet(fio_burn) for fio_burn in get_fio_burn(args.planets)]
 	if args.include_ship:
-		stores: typing.Sequence[Storage] = cache.get('https://rest.fnar.net/storage/' + config.username,
+		stores: typing.Sequence[market.Storage] = cache.get('https://rest.fnar.net/storage/' + config.username,
 				headers={'Authorization': config.fio_api_key})
 		for ship in args.include_ship:
 			ship_name, planet_name = ship.casefold().split('=')
@@ -158,7 +158,7 @@ class FIOBurn(typing.TypedDict):
 	Error: typing.Any
 	OrderConsumption: list[Amount]
 	WorkforceConsumption: list[Amount]
-	Inventory: list[Inventory]
+	Inventory: list[market.StorageItem]
 	OrderProduction: list[Amount]
 
 @dataclasses.dataclass(init=False, eq=False, slots=True)
@@ -197,15 +197,6 @@ class Amount(typing.TypedDict):
 	DailyAmount: float
 	net_consumption: float
 
-class Inventory(typing.TypedDict):
-	MaterialTicker: str
-	MaterialAmount: int
-
-class Storage(typing.TypedDict):
-	Name: str
-	StorageItems: list[Inventory]
-	Type: typing.Literal['STORE'] | typing.Literal['WAREHOUSE_STORE'] | typing.Literal['FTL_FUEL_STORE'] | typing.Literal['STL_FUEL_STORE'] |  typing.Literal['SHIP_STORE']
-
 class Material(typing.TypedDict):
 	Ticker: str
 	Weight: float