|
@@ -20,13 +20,13 @@ def main() -> None:
|
|
|
for recipe in recipes:
|
|
for recipe in recipes:
|
|
|
if profit := calc_profit(recipe, buildings, materials, prices):
|
|
if profit := calc_profit(recipe, buildings, materials, prices):
|
|
|
profits.append(profit)
|
|
profits.append(profit)
|
|
|
- profits.sort(reverse=True)
|
|
|
|
|
|
|
+ profits.sort()
|
|
|
print('\033[1mwrought \033[0;32mdaily profit/area\033[31m')
|
|
print('\033[1mwrought \033[0;32mdaily profit/area\033[31m')
|
|
|
print('\033[30mrecipe \033[0mexpertise \033[33mcapex \033[35mdaily opex \033[34mlogistics\033[0m')
|
|
print('\033[30mrecipe \033[0mexpertise \033[33mcapex \033[35mdaily opex \033[34mlogistics\033[0m')
|
|
|
for p in profits:
|
|
for p in profits:
|
|
|
- print(f'\033[53;1m{p.output:5} \033[53;32m{p.profit_per_area: 10,.0f} ', end='')
|
|
|
|
|
|
|
+ print(f'\033[53;1m{p.output:5} \033[53;32m{p.profit_per_day/p.area: 10,.0f} ', end='')
|
|
|
warnings = []
|
|
warnings = []
|
|
|
- if p.low_volume:
|
|
|
|
|
|
|
+ if p.average_traded_7d < p.output_per_day * 20:
|
|
|
warnings.append('low volume')
|
|
warnings.append('low volume')
|
|
|
if p.logistics_per_area > 1.5:
|
|
if p.logistics_per_area > 1.5:
|
|
|
warnings.append('heavy logistics')
|
|
warnings.append('heavy logistics')
|
|
@@ -69,11 +69,13 @@ def calc_profit(recipe: Recipe, buildings: typing.Mapping[str, Building], materi
|
|
|
) * runs_per_day / building['AreaCost']
|
|
) * runs_per_day / building['AreaCost']
|
|
|
return Profit(output['Ticker'], recipe['RecipeName'],
|
|
return Profit(output['Ticker'], recipe['RecipeName'],
|
|
|
expertise=building['Expertise'].replace('_', ' ').lower(),
|
|
expertise=building['Expertise'].replace('_', ' ').lower(),
|
|
|
- profit_per_area=(profit_per_run * runs_per_day - worker_consumable_daily_cost) / building['AreaCost'],
|
|
|
|
|
|
|
+ profit_per_day=(profit_per_run * runs_per_day - worker_consumable_daily_cost),
|
|
|
|
|
+ area=building['AreaCost'],
|
|
|
capex=capex,
|
|
capex=capex,
|
|
|
cost_per_day=cost_per_day,
|
|
cost_per_day=cost_per_day,
|
|
|
logistics_per_area=logistics_per_area,
|
|
logistics_per_area=logistics_per_area,
|
|
|
- low_volume=output_price.average_traded < output_per_day * 20)
|
|
|
|
|
|
|
+ output_per_day=output_per_day,
|
|
|
|
|
+ average_traded_7d=output_price.average_traded_7d)
|
|
|
|
|
|
|
|
def building_daily_cost(building: Building, prices: typing.Mapping[str, Price]) -> float:
|
|
def building_daily_cost(building: Building, prices: typing.Mapping[str, Price]) -> float:
|
|
|
consumption = {
|
|
consumption = {
|
|
@@ -131,27 +133,27 @@ class RawPrice(typing.TypedDict):
|
|
|
@dataclasses.dataclass(eq=False, frozen=True, slots=True)
|
|
@dataclasses.dataclass(eq=False, frozen=True, slots=True)
|
|
|
class Price:
|
|
class Price:
|
|
|
vwap: float
|
|
vwap: float
|
|
|
- average_traded: float
|
|
|
|
|
|
|
+ average_traded_7d: float
|
|
|
|
|
|
|
|
-@dataclasses.dataclass(eq=False, slots=True)
|
|
|
|
|
|
|
+@dataclasses.dataclass(eq=False, frozen=True, slots=True)
|
|
|
class Profit:
|
|
class Profit:
|
|
|
output: str
|
|
output: str
|
|
|
recipe: str
|
|
recipe: str
|
|
|
expertise: str
|
|
expertise: str
|
|
|
- profit_per_area: float
|
|
|
|
|
|
|
+ profit_per_day: float
|
|
|
|
|
+ area: float
|
|
|
capex: float
|
|
capex: float
|
|
|
cost_per_day: float
|
|
cost_per_day: float
|
|
|
logistics_per_area: float
|
|
logistics_per_area: float
|
|
|
- low_volume: bool
|
|
|
|
|
- score: float = dataclasses.field(init=False)
|
|
|
|
|
-
|
|
|
|
|
- def __post_init__(self) -> None:
|
|
|
|
|
- self.score = self.profit_per_area
|
|
|
|
|
- if self.low_volume:
|
|
|
|
|
- self.score *= 0.2
|
|
|
|
|
|
|
+ output_per_day: float
|
|
|
|
|
+ average_traded_7d: float
|
|
|
|
|
|
|
|
def __lt__(self, other: Profit) -> bool:
|
|
def __lt__(self, other: Profit) -> bool:
|
|
|
- return self.score < other.score
|
|
|
|
|
|
|
+ if (break_even := self.capex / self.profit_per_day) < 0:
|
|
|
|
|
+ break_even = 10000 - self.profit_per_day
|
|
|
|
|
+ if (other_break_even := other.capex / other.profit_per_day) < 0:
|
|
|
|
|
+ other_break_even = 10000 - other.profit_per_day
|
|
|
|
|
+ return break_even < other_break_even
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
if __name__ == '__main__':
|
|
|
main()
|
|
main()
|