|
|
@@ -6,6 +6,13 @@ import typing
|
|
|
import cache
|
|
|
import roi
|
|
|
|
|
|
+BUY = frozenset([
|
|
|
+ # definitely buy
|
|
|
+ 'C', 'FLX', 'H', 'H2O', 'HAL', 'HCP', 'HE', 'LST', 'MG', 'N', 'NA', 'NCS', 'NS', 'O', 'PE', 'PG', 'S', 'TCL',
|
|
|
+ # maybe buy
|
|
|
+ 'AU', 'BRM', 'CU', 'FE', 'LI', 'RG', 'ROM', 'SI', 'TI',
|
|
|
+])
|
|
|
+
|
|
|
def main() -> None:
|
|
|
blueprint = {
|
|
|
'FFC': 1,
|
|
|
@@ -26,17 +33,32 @@ def main() -> None:
|
|
|
for p in cache.get('https://refined-prun.github.io/refined-prices/all.json') if p['ExchangeCode'] == 'IC1'}
|
|
|
recipes = recipe_for_mats()
|
|
|
|
|
|
- buildings: dict[str, set[str]] = collections.defaultdict(set)
|
|
|
+ production: dict[str, dict[str, float]] = collections.defaultdict(lambda: collections.defaultdict(float))
|
|
|
cost = 0.0
|
|
|
for mat, amount in blueprint.items():
|
|
|
- cost += analyze_mat(0, mat, amount, buildings, prices, recipes)
|
|
|
+ cost += analyze_mat(0, mat, amount, production, prices, recipes)
|
|
|
print()
|
|
|
print(f'total cost: {cost:,}')
|
|
|
- for building, mats in buildings.items():
|
|
|
- print(f'{building:3}: {", ".join(mats)}')
|
|
|
+
|
|
|
+ buildings: typing.Sequence[roi.Building] = cache.get('https://api.prunplanner.org/data/buildings/', expiry=cache.ONE_DAY)
|
|
|
+ expertise = collections.defaultdict(list)
|
|
|
+ for building in buildings:
|
|
|
+ if building['building_ticker'] in production:
|
|
|
+ expertise[building['expertise']].append(building['building_ticker'])
|
|
|
+ for expertise, buildings in expertise.items():
|
|
|
+ print(expertise)
|
|
|
+ for building in buildings:
|
|
|
+ print(f'\t{building:3}:', end='')
|
|
|
+ for mat, amount in production[building].items():
|
|
|
+ traded = prices[mat]['AverageTraded30D'] or 0
|
|
|
+ if traded > amount * 2:
|
|
|
+ print(f' \033[32m{mat}\033[0m', end='')
|
|
|
+ else:
|
|
|
+ print(f' \033[31m{mat}\033[0m', end='')
|
|
|
+ print()
|
|
|
|
|
|
def recipe_for_mats() -> dict[str, roi.Recipe]:
|
|
|
- all_recipes: list[roi.Recipe] = cache.get('https://api.prunplanner.org/data/recipes/')
|
|
|
+ all_recipes: list[roi.Recipe] = cache.get('https://api.prunplanner.org/data/recipes/', expiry=cache.ONE_DAY)
|
|
|
mat_recipes = collections.defaultdict(list) # all ways to make a mat
|
|
|
for recipe in all_recipes:
|
|
|
for output in recipe['outputs']:
|
|
|
@@ -48,12 +70,12 @@ def recipe_for_mats() -> dict[str, roi.Recipe]:
|
|
|
mat_recipe[mat] = recipes[0]
|
|
|
return mat_recipe
|
|
|
|
|
|
-def analyze_mat(level: int, mat: str, amount: float, buildings: dict[str, set[str]],
|
|
|
+def analyze_mat(level: int, mat: str, amount: float, production: dict[str, dict[str, float]],
|
|
|
prices: typing.Mapping[str, RawPrice], recipes: dict[str, roi.Recipe]) -> float:
|
|
|
price = prices[mat]
|
|
|
traded = price['AverageTraded30D'] or 0
|
|
|
- if (price['Supply'] > amount * 10 and traded > 0) or (price['Supply'] > amount * 4 and amount < traded):
|
|
|
- print('\t' * level + f'{amount:g}×{mat} buy: {price["Ask"]:9,}, daily traded {traded:5.1f}, supply {price["Supply"]:4}')
|
|
|
+ if mat in BUY:
|
|
|
+ print('\t' * level + f'{amount:g}×{mat} buy: {price["Ask"]}, daily traded {traded:5.1f}')
|
|
|
assert price['Ask'] is not None
|
|
|
return price['Ask'] * amount
|
|
|
else:
|
|
|
@@ -62,12 +84,17 @@ def analyze_mat(level: int, mat: str, amount: float, buildings: dict[str, set[st
|
|
|
return 0
|
|
|
else:
|
|
|
building = recipe['building_ticker']
|
|
|
- print('\t' * level + f'{amount:g}×{mat} make ({building})')
|
|
|
- buildings[building].add(mat)
|
|
|
+ production[building][mat] += amount
|
|
|
+
|
|
|
+ liquid = '\033[31mnot liquid\033[0m'
|
|
|
+ if traded > amount * 2:
|
|
|
+ liquid = '\033[32mliquid\033[0m'
|
|
|
+ print('\t' * level + f'{amount:g}×{mat} make ({building}, {liquid})')
|
|
|
+
|
|
|
total_cost = 0.0
|
|
|
for input_mat in recipe['inputs']:
|
|
|
input_amount = input_mat['material_amount'] * amount / recipe['outputs'][0]['material_amount']
|
|
|
- total_cost += analyze_mat(level + 1, input_mat['material_ticker'], input_amount, buildings, prices, recipes)
|
|
|
+ total_cost += analyze_mat(level + 1, input_mat['material_ticker'], input_amount, production, prices, recipes)
|
|
|
print('\t' * level + f'\tcost: {total_cost:9,.2f}')
|
|
|
return total_cost
|
|
|
|