Browse Source

Merge branch 'feature/integrate-chart-to-snapshot-calculation' of https://github.com/gizmodus/ghostfolio into pr/3271

pull/3383/head
Thomas Kaul 1 year ago
parent
commit
10ed5d07a0
  1. 14
      apps/api/src/app/portfolio/calculator/portfolio-calculator.ts
  2. 46
      apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts
  3. 1
      apps/api/src/app/portfolio/interfaces/portfolio-order-item.interface.ts

14
apps/api/src/app/portfolio/calculator/portfolio-calculator.ts

@ -91,6 +91,7 @@ export abstract class PortfolioCalculator {
userId: string; userId: string;
}) { }) {
console.time('--- PortfolioCalculator.constructor - 1'); console.time('--- PortfolioCalculator.constructor - 1');
this.accountBalanceItems = accountBalanceItems; this.accountBalanceItems = accountBalanceItems;
this.configurationService = configurationService; this.configurationService = configurationService;
this.currency = currency; this.currency = currency;
@ -273,7 +274,8 @@ export abstract class PortfolioCalculator {
} = await this.currentRateService.getValues({ } = await this.currentRateService.getValues({
dataGatheringItems, dataGatheringItems,
dateQuery: { dateQuery: {
in: dates gte: parseDate(firstTransactionPoint?.date),
lt: end
} }
}); });
@ -302,7 +304,7 @@ export abstract class PortfolioCalculator {
const chartStartDate = this.getStartDate(); const chartStartDate = this.getStartDate();
const daysInMarket = differenceInDays(endDate, chartStartDate) + 1; const daysInMarket = differenceInDays(endDate, chartStartDate) + 1;
const step = true /*withDataDecimation*/ const step = false /*withDataDecimation*/
? Math.round(daysInMarket / Math.min(daysInMarket, MAX_CHART_ITEMS)) ? Math.round(daysInMarket / Math.min(daysInMarket, MAX_CHART_ITEMS))
: 1; : 1;
@ -581,11 +583,6 @@ export abstract class PortfolioCalculator {
totalTimeWeightedInvestmentValueWithCurrencyEffect totalTimeWeightedInvestmentValueWithCurrencyEffect
} = values; } = values;
console.log(
'Chart: totalTimeWeightedInvestmentValue',
totalTimeWeightedInvestmentValue.toFixed()
);
const netPerformanceInPercentage = totalTimeWeightedInvestmentValue.eq(0) const netPerformanceInPercentage = totalTimeWeightedInvestmentValue.eq(0)
? 0 ? 0
: totalNetPerformanceValue : totalNetPerformanceValue
@ -712,7 +709,8 @@ export abstract class PortfolioCalculator {
await this.currentRateService.getValues({ await this.currentRateService.getValues({
dataGatheringItems, dataGatheringItems,
dateQuery: { dateQuery: {
in: dates gte: start,
lt: end
} }
}); });

46
apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts

@ -337,18 +337,23 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
let lastUnitPrice: Big; let lastUnitPrice: Big;
if (isChartMode) { if (isChartMode) {
const datesWithOrders = {}; const ordersByDate: { [date: string]: PortfolioOrderItem[] } = {};
for (const { date, type } of orders) { for (const order of orders) {
if (['BUY', 'SELL'].includes(type)) { if (['BUY', 'SELL'].includes(order.type)) {
datesWithOrders[date] = true; ordersByDate[order.date] = ordersByDate[order.date] ?? [];
ordersByDate[order.date].push(order);
} }
} }
while (isBefore(day, end)) { while (isBefore(day, end)) {
const hasDate = datesWithOrders[format(day, DATE_FORMAT)]; if (ordersByDate[format(day, DATE_FORMAT)]?.length > 0) {
for (let order of ordersByDate[format(day, DATE_FORMAT)]) {
if (!hasDate) { order.unitPriceFromMarketData =
marketSymbolMap[format(day, DATE_FORMAT)]?.[symbol] ??
lastUnitPrice;
}
} else {
orders.push({ orders.push({
date: format(day, DATE_FORMAT), date: format(day, DATE_FORMAT),
fee: new Big(0), fee: new Big(0),
@ -360,12 +365,18 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
}, },
type: 'BUY', type: 'BUY',
unitPrice: unitPrice:
marketSymbolMap[format(day, DATE_FORMAT)]?.[symbol] ??
lastUnitPrice,
unitPriceFromMarketData:
marketSymbolMap[format(day, DATE_FORMAT)]?.[symbol] ?? marketSymbolMap[format(day, DATE_FORMAT)]?.[symbol] ??
lastUnitPrice lastUnitPrice
}); });
} }
lastUnitPrice = last(orders).unitPrice; const lastOrder = last(orders);
lastUnitPrice =
lastOrder.unitPriceFromMarketData ?? lastOrder.unitPrice;
day = addDays(day, step); day = addDays(day, step);
} }
@ -459,12 +470,14 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
); );
} }
if (order.unitPrice) { const unitPrice = ['BUY', 'SELL'].includes(order.type)
order.unitPriceInBaseCurrency = order.unitPrice.mul( ? order.unitPrice
currentExchangeRate ?? 1 : order.unitPriceFromMarketData;
);
if (unitPrice) {
order.unitPriceInBaseCurrency = unitPrice.mul(currentExchangeRate ?? 1);
order.unitPriceInBaseCurrencyWithCurrencyEffect = order.unitPrice.mul( order.unitPriceInBaseCurrencyWithCurrencyEffect = unitPrice.mul(
exchangeRateAtOrderDate ?? 1 exchangeRateAtOrderDate ?? 1
); );
} }
@ -648,10 +661,13 @@ export class TWRPortfolioCalculator extends PortfolioCalculator {
grossPerformanceWithCurrencyEffect; grossPerformanceWithCurrencyEffect;
} }
if (i > indexOfStartOrder && ['BUY', 'SELL'].includes(order.type)) { if (i > indexOfStartOrder) {
// Only consider periods with an investment for the calculation of // Only consider periods with an investment for the calculation of
// the time weighted investment // the time weighted investment
if (valueOfInvestmentBeforeTransaction.gt(0)) { if (
valueOfInvestmentBeforeTransaction.gt(0) &&
['BUY', 'SELL'].includes(order.type)
) {
// Calculate the number of days since the previous order // Calculate the number of days since the previous order
const orderDate = new Date(order.date); const orderDate = new Date(order.date);
const previousOrderDate = new Date(orders[i - 1].date); const previousOrderDate = new Date(orders[i - 1].date);

1
apps/api/src/app/portfolio/interfaces/portfolio-order-item.interface.ts

@ -6,6 +6,7 @@ export interface PortfolioOrderItem extends PortfolioOrder {
feeInBaseCurrency?: Big; feeInBaseCurrency?: Big;
feeInBaseCurrencyWithCurrencyEffect?: Big; feeInBaseCurrencyWithCurrencyEffect?: Big;
itemType?: 'end' | 'start'; itemType?: 'end' | 'start';
unitPriceFromMarketData?: Big;
unitPriceInBaseCurrency?: Big; unitPriceInBaseCurrency?: Big;
unitPriceInBaseCurrencyWithCurrencyEffect?: Big; unitPriceInBaseCurrencyWithCurrencyEffect?: Big;
} }

Loading…
Cancel
Save