From 30151774ccd72dce47af000b3160f80e79e200aa Mon Sep 17 00:00:00 2001 From: Reto Kaul Date: Sun, 5 May 2024 16:55:20 +0200 Subject: [PATCH] Fix chart --- .../calculator/portfolio-calculator.ts | 13 ++--- .../calculator/twr/portfolio-calculator.ts | 47 ++++++++++++------- .../portfolio-order-item.interface.ts | 1 + 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index ad043f657..5f8a488f0 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -231,7 +231,8 @@ export abstract class PortfolioCalculator { } = await this.currentRateService.getValues({ dataGatheringItems, dateQuery: { - in: dates + gte: parseDate(firstTransactionPoint?.date), + lt: end } }); @@ -260,7 +261,7 @@ export abstract class PortfolioCalculator { const chartStartDate = this.getStartDate(); const daysInMarket = differenceInDays(endDate, chartStartDate) + 1; - const step = true /*withDataDecimation*/ + const step = false /*withDataDecimation*/ ? Math.round(daysInMarket / Math.min(daysInMarket, MAX_CHART_ITEMS)) : 1; @@ -539,11 +540,6 @@ export abstract class PortfolioCalculator { totalTimeWeightedInvestmentValueWithCurrencyEffect } = values; - console.log( - 'Chart: totalTimeWeightedInvestmentValue', - totalTimeWeightedInvestmentValue.toFixed() - ); - const netPerformanceInPercentage = totalTimeWeightedInvestmentValue.eq(0) ? 0 : totalNetPerformanceValue @@ -670,7 +666,8 @@ export abstract class PortfolioCalculator { await this.currentRateService.getValues({ dataGatheringItems, dateQuery: { - in: dates + gte: start, + lt: end } }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index c60f9a9f8..ddc71dacb 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -102,11 +102,6 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { } } - console.log( - 'Overall: totalTimeWeightedInvestmentValue', - totalTimeWeightedInvestment.toFixed() - ); - return { currentValueInBaseCurrency, grossPerformance, @@ -338,16 +333,21 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { let lastUnitPrice: Big; if (isChartMode) { - const datesWithOrders = {}; + const ordersByDate: { [date: string]: PortfolioOrderItem[] } = {}; for (const order of orders) { - datesWithOrders[order.date] = true; + ordersByDate[order.date] = ordersByDate[order.date] ?? []; + ordersByDate[order.date].push(order); } while (isBefore(day, end)) { - const hasDate = datesWithOrders[format(day, DATE_FORMAT)]; - - if (!hasDate) { + if (ordersByDate[format(day, DATE_FORMAT)]?.length > 0) { + for (let order of ordersByDate[format(day, DATE_FORMAT)]) { + order.unitPriceFromMarketData = + marketSymbolMap[format(day, DATE_FORMAT)]?.[symbol] ?? + lastUnitPrice; + } + } else { orders.push({ date: format(day, DATE_FORMAT), fee: new Big(0), @@ -359,12 +359,18 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { }, type: 'BUY', unitPrice: + marketSymbolMap[format(day, DATE_FORMAT)]?.[symbol] ?? + lastUnitPrice, + unitPriceFromMarketData: marketSymbolMap[format(day, DATE_FORMAT)]?.[symbol] ?? lastUnitPrice }); } - lastUnitPrice = last(orders).unitPrice; + const lastOrder = last(orders); + + lastUnitPrice = + lastOrder.unitPriceFromMarketData ?? lastOrder.unitPrice; day = addDays(day, step); } @@ -423,12 +429,14 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { ); } - if (order.unitPrice) { - order.unitPriceInBaseCurrency = order.unitPrice.mul( - currentExchangeRate ?? 1 - ); + const unitPrice = ['BUY', 'SELL'].includes(order.type) + ? order.unitPrice + : order.unitPriceFromMarketData; + + if (unitPrice) { + order.unitPriceInBaseCurrency = unitPrice.mul(currentExchangeRate ?? 1); - order.unitPriceInBaseCurrencyWithCurrencyEffect = order.unitPrice.mul( + order.unitPriceInBaseCurrencyWithCurrencyEffect = unitPrice.mul( exchangeRateAtOrderDate ?? 1 ); } @@ -649,10 +657,13 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { grossPerformanceWithCurrencyEffect; } - if (i > indexOfStartOrder && ['BUY', 'SELL'].includes(order.type)) { + if (i > indexOfStartOrder) { // Only consider periods with an investment for the calculation of // 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 const orderDate = new Date(order.date); const previousOrderDate = new Date(orders[i - 1].date); diff --git a/apps/api/src/app/portfolio/interfaces/portfolio-order-item.interface.ts b/apps/api/src/app/portfolio/interfaces/portfolio-order-item.interface.ts index b0543ce99..06e471d67 100644 --- a/apps/api/src/app/portfolio/interfaces/portfolio-order-item.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/portfolio-order-item.interface.ts @@ -6,6 +6,7 @@ export interface PortfolioOrderItem extends PortfolioOrder { feeInBaseCurrency?: Big; feeInBaseCurrencyWithCurrencyEffect?: Big; itemType?: 'end' | 'start'; + unitPriceFromMarketData?: Big; unitPriceInBaseCurrency?: Big; unitPriceInBaseCurrencyWithCurrencyEffect?: Big; }