From 986fb181b7c3b78c158af6b1b1fd28108ec042b3 Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 3 May 2025 10:47:01 +0200 Subject: [PATCH] Reset Graph to 0 at start of time period --- .../calculator/portfolio-calculator.ts | 58 ++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index 726a79b74..d5c660479 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -745,6 +745,10 @@ export abstract class PortfolioCalculator { let netPerformanceAtStartDate: number; let netPerformanceWithCurrencyEffectAtStartDate: number; + let lastTimeWeightedPerformancePercentage: number; + let lastTimeWeightedPerformancePercentageWithCurrencyEffect: number; + let timeWeightedPerformanceInPercentage: number; + let timeWeightedPerformanceInPercentageWithCurrencyEffect: number; const totalInvestmentValuesWithCurrencyEffect: number[] = []; for (const historicalDataItem of historicalData) { @@ -777,7 +781,19 @@ export abstract class PortfolioCalculator { totalInvestmentValuesWithCurrencyEffect.length : 0; - //TODO : Extract in abstractFunction and use timeweighted for ROI + Handle total values separately + ({ + timeWeightedPerformanceInPercentage, + timeWeightedPerformanceInPercentageWithCurrencyEffect, + lastTimeWeightedPerformancePercentage, + lastTimeWeightedPerformancePercentageWithCurrencyEffect + } = this.calculateTimeWeightedPerformance( + lastTimeWeightedPerformancePercentage, + historicalDataItem, + lastTimeWeightedPerformancePercentageWithCurrencyEffect, + timeWeightedPerformanceInPercentage, + timeWeightedPerformanceInPercentageWithCurrencyEffect + )); + chart.push({ ...historicalDataItem, netPerformance: @@ -792,7 +808,9 @@ export abstract class PortfolioCalculator { timeWeightedInvestmentValue === 0 ? 0 : netPerformanceWithCurrencyEffectSinceStartDate / - timeWeightedInvestmentValue + timeWeightedInvestmentValue, + timeWeightedPerformanceInPercentage, + timeWeightedPerformanceInPercentageWithCurrencyEffect // TODO: Add net worth with valuables // netWorth: totalCurrentValueWithCurrencyEffect // .plus(totalAccountBalanceWithCurrencyEffect) @@ -818,6 +836,42 @@ export abstract class PortfolioCalculator { }; } + private calculateTimeWeightedPerformance( + lastTimeWeightedPerformancePercentage: number, + historicalDataItem: HistoricalDataItem, + lastTimeWeightedPerformancePercentageWithCurrencyEffect: number, + timeWeightedPerformanceInPercentage: number, + timeWeightedPerformanceInPercentageWithCurrencyEffect: number + ): { + timeWeightedPerformanceInPercentage: number; + timeWeightedPerformanceInPercentageWithCurrencyEffect: number; + lastTimeWeightedPerformancePercentage: number; + lastTimeWeightedPerformancePercentageWithCurrencyEffect: number; + } { + timeWeightedPerformanceInPercentage = lastTimeWeightedPerformancePercentage + ? (1 + timeWeightedPerformanceInPercentage) * + ((1 + historicalDataItem.timeWeightedPerformanceInPercentage) / + (1 + lastTimeWeightedPerformancePercentage)) - + 1 + : 0; + timeWeightedPerformanceInPercentageWithCurrencyEffect = + lastTimeWeightedPerformancePercentageWithCurrencyEffect + ? (1 + timeWeightedPerformanceInPercentageWithCurrencyEffect) * + ((1 + + historicalDataItem.timeWeightedPerformanceInPercentageWithCurrencyEffect) / + (1 + lastTimeWeightedPerformancePercentageWithCurrencyEffect)) - + 1 + : 0; + return { + timeWeightedPerformanceInPercentage, + timeWeightedPerformanceInPercentageWithCurrencyEffect, + lastTimeWeightedPerformancePercentage: + historicalDataItem.timeWeightedPerformanceInPercentage, + lastTimeWeightedPerformancePercentageWithCurrencyEffect: + historicalDataItem.timeWeightedPerformanceInPercentageWithCurrencyEffect + }; + } + @LogPerformance protected getHistoricalDataItems(accumulatedValuesByDate: { [date: string]: {