|
@@ -11,6 +11,13 @@ interface Price {
|
|
|
MaterialTicker: string;
|
|
MaterialTicker: string;
|
|
|
ExchangeCode: string;
|
|
ExchangeCode: string;
|
|
|
PriceAverage: number;
|
|
PriceAverage: number;
|
|
|
|
|
+ Traded: number;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+interface RecipeProfit {
|
|
|
|
|
+ recipeName: string;
|
|
|
|
|
+ dailyProfit: number;
|
|
|
|
|
+ traded: number;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async function fetchData(): Promise<{recipes: Recipe[]; prices: Price[]}> {
|
|
async function fetchData(): Promise<{recipes: Recipe[]; prices: Price[]}> {
|
|
@@ -26,40 +33,43 @@ async function fetchData(): Promise<{recipes: Recipe[]; prices: Price[]}> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function render({recipes, prices}: {recipes: Recipe[], prices: Price[]}) {
|
|
function render({recipes, prices}: {recipes: Recipe[], prices: Price[]}) {
|
|
|
- const priceMap = new Map<string, number>();
|
|
|
|
|
|
|
+ const priceMap = new Map<string, Price>();
|
|
|
for (const price of prices)
|
|
for (const price of prices)
|
|
|
if (price.ExchangeCode == 'PP7D_IC1')
|
|
if (price.ExchangeCode == 'PP7D_IC1')
|
|
|
- priceMap.set(price.MaterialTicker, price.PriceAverage);
|
|
|
|
|
-
|
|
|
|
|
- const fmt = new Intl.NumberFormat(undefined, {maximumFractionDigits: 2});
|
|
|
|
|
|
|
+ priceMap.set(price.MaterialTicker, price);
|
|
|
|
|
|
|
|
- const tbody = document.querySelector('tbody') as HTMLTableSectionElement;
|
|
|
|
|
- tbody.innerHTML = '';
|
|
|
|
|
|
|
+ const profits: RecipeProfit[] = []
|
|
|
for (const recipe of recipes) {
|
|
for (const recipe of recipes) {
|
|
|
- if (recipe.BuildingTicker !== 'FRM')
|
|
|
|
|
- continue;
|
|
|
|
|
const runsPerDay = 1000 * 60 * 60 * 24 / recipe.TimeMs;
|
|
const runsPerDay = 1000 * 60 * 60 * 24 / recipe.TimeMs;
|
|
|
-
|
|
|
|
|
- const revenuePerRun = recipe.Outputs.reduce((sum, output) => {
|
|
|
|
|
- const price = priceMap.get(output.Ticker);
|
|
|
|
|
- if (price === undefined)
|
|
|
|
|
- throw new Error(`missing price for ${output.Ticker}`);
|
|
|
|
|
- return sum + price * output.Amount;
|
|
|
|
|
- }, 0);
|
|
|
|
|
-
|
|
|
|
|
|
|
+ if (recipe.Outputs.length !== 1) {
|
|
|
|
|
+ console.warn(`${recipe.RecipeName} doesn't have 1 output`);
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ const output = recipe.Outputs[0];
|
|
|
|
|
+ const outputPrice = priceMap.get(output.Ticker);
|
|
|
|
|
+ if (outputPrice === undefined)
|
|
|
|
|
+ throw new Error(`missing price for ${output.Ticker}`);
|
|
|
|
|
+ const revenuePerRun = output.Amount * outputPrice.PriceAverage;
|
|
|
const costPerRun = recipe.Inputs.reduce((sum, input) => {
|
|
const costPerRun = recipe.Inputs.reduce((sum, input) => {
|
|
|
const price = priceMap.get(input.Ticker);
|
|
const price = priceMap.get(input.Ticker);
|
|
|
if (price === undefined)
|
|
if (price === undefined)
|
|
|
throw new Error(`missing price for ${input.Ticker}`);
|
|
throw new Error(`missing price for ${input.Ticker}`);
|
|
|
- return sum + price * input.Amount;
|
|
|
|
|
|
|
+ return sum + price.PriceAverage * input.Amount;
|
|
|
}, 0);
|
|
}, 0);
|
|
|
|
|
+ const dailyProfit = (revenuePerRun - costPerRun) * runsPerDay;
|
|
|
|
|
+ profits.push({ recipeName: recipe.RecipeName, dailyProfit, traded: outputPrice.Traded });
|
|
|
|
|
+ }
|
|
|
|
|
+ profits.sort((a, b) => b.dailyProfit - a.dailyProfit);
|
|
|
|
|
|
|
|
|
|
+ const fmt = new Intl.NumberFormat(undefined, {maximumFractionDigits: 2});
|
|
|
|
|
+ const tbody = document.querySelector('tbody') as HTMLTableSectionElement;
|
|
|
|
|
+ tbody.innerHTML = '';
|
|
|
|
|
+ for (const profit of profits) {
|
|
|
const row = document.createElement('tr');
|
|
const row = document.createElement('tr');
|
|
|
row.innerHTML = `
|
|
row.innerHTML = `
|
|
|
- <td>${recipe.RecipeName}</td>
|
|
|
|
|
- <td>${fmt.format(revenuePerRun * runsPerDay)}</td>
|
|
|
|
|
- <td>${fmt.format(costPerRun * runsPerDay)}</td>
|
|
|
|
|
- <td>${fmt.format((revenuePerRun - costPerRun) * runsPerDay)}</td>
|
|
|
|
|
|
|
+ <td>${profit.recipeName}</td>
|
|
|
|
|
+ <td>${fmt.format(profit.dailyProfit)}</td>
|
|
|
|
|
+ <td>${fmt.format(profit.traded)}</td>
|
|
|
`;
|
|
`;
|
|
|
tbody.appendChild(row);
|
|
tbody.appendChild(row);
|
|
|
}
|
|
}
|