38 lines
1.2 KiB
TypeScript
38 lines
1.2 KiB
TypeScript
import { add, decimal, formatDecimal, isZero, multiply } from './decimal';
|
|
import { MoneyDto } from './portfolio.dto';
|
|
import { TbankPortfolio, TbankPositions } from './tbank.client';
|
|
|
|
function totalsByCurrency(
|
|
positions: NonNullable<TbankPortfolio['positions']>,
|
|
money: NonNullable<TbankPositions['money']>,
|
|
): MoneyDto[] {
|
|
const totals = new Map<string, ReturnType<typeof decimal>>();
|
|
const addTotal = (
|
|
currency: string | undefined,
|
|
amount: ReturnType<typeof decimal>,
|
|
) => {
|
|
const normalizedCurrency = currency?.trim().toUpperCase();
|
|
if (!normalizedCurrency || isZero(amount)) return;
|
|
totals.set(
|
|
normalizedCurrency,
|
|
add(totals.get(normalizedCurrency) ?? decimal({}), amount),
|
|
);
|
|
};
|
|
|
|
for (const value of money) addTotal(value.currency, decimal(value));
|
|
for (const position of positions) {
|
|
const price = position.currentPrice;
|
|
if (!price) continue;
|
|
addTotal(
|
|
price.currency,
|
|
multiply(decimal(position.quantity ?? {}), decimal(price)),
|
|
);
|
|
}
|
|
|
|
return [...totals]
|
|
.filter(([, value]) => !isZero(value))
|
|
.map(([currency, value]) => ({ currency, value: formatDecimal(value) }));
|
|
}
|
|
|
|
export { totalsByCurrency };
|