From d373b5aa621f32336fc0af3c1eb65870bc76391b Mon Sep 17 00:00:00 2001 From: bptrgx <47859535+bptrgx@users.noreply.github.com> Date: Fri, 30 May 2025 21:29:04 +0200 Subject: [PATCH 1/5] fix portfolio calculator logger --- .../app/portfolio/calculator/roai/portfolio-calculator.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts index d9da465f9..99d569be9 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts @@ -938,9 +938,11 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator { Net performance: ${totalNetPerformance.toFixed( 2 )} / ${netPerformancePercentage.mul(100).toFixed(2)}% - Net performance with currency effect: ${netPerformancePercentageWithCurrencyEffectMap[ - 'max' - ].toFixed(2)}%` + Net performance with currency effect: ${netPerformanceValuesWithCurrencyEffect[ + endDateString + ].toFixed(2)} / ${netPerformancePercentageWithCurrencyEffectMap['max'] + .mul(100) + .toFixed(2)}%` ); } From 6db676e636d63cb48d799bb5c95f79646fce860a Mon Sep 17 00:00:00 2001 From: bptrgx <47859535+bptrgx@users.noreply.github.com> Date: Fri, 30 May 2025 21:29:06 +0200 Subject: [PATCH 2/5] performance percentage is 100% if average buy price is zero and performance value is not null --- .../calculator/roai/portfolio-calculator.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts index 99d569be9..2d6afab99 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts @@ -783,7 +783,9 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator { ? totalGrossPerformance.div( timeWeightedAverageInvestmentBetweenStartAndEndDate ) - : new Big(0); + : totalGrossPerformance + ? new Big(1) + : new Big(0); const grossPerformancePercentageWithCurrencyEffect = timeWeightedAverageInvestmentBetweenStartAndEndDateWithCurrencyEffect.gt( @@ -792,7 +794,9 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator { ? totalGrossPerformanceWithCurrencyEffect.div( timeWeightedAverageInvestmentBetweenStartAndEndDateWithCurrencyEffect ) - : new Big(0); + : totalGrossPerformanceWithCurrencyEffect + ? new Big(1) + : new Big(0); const feesPerUnit = totalUnits.gt(0) ? fees.minus(feesAtStartDate).div(totalUnits) @@ -809,7 +813,9 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator { ? totalNetPerformance.div( timeWeightedAverageInvestmentBetweenStartAndEndDate ) - : new Big(0); + : totalNetPerformance + ? new Big(1) + : new Big(0); const netPerformancePercentageWithCurrencyEffectMap: { [key: DateRange]: Big; @@ -902,7 +908,9 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator { netPerformancePercentageWithCurrencyEffectMap[dateRange] = average.gt(0) ? netPerformanceWithCurrencyEffectMap[dateRange].div(average) - : new Big(0); + : netPerformanceWithCurrencyEffectMap[dateRange] + ? new Big(1) + : new Big(0); } if (PortfolioCalculator.ENABLE_LOGGING) { From 5276f2280f943d1a3f32c07508d23f7485c1ac71 Mon Sep 17 00:00:00 2001 From: bptrgx <47859535+bptrgx@users.noreply.github.com> Date: Fri, 30 May 2025 21:29:08 +0200 Subject: [PATCH 3/5] do not use the average buy price as the first value of the market price chart --- apps/api/src/app/portfolio/portfolio.service.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 7e373c4cc..06d2b0406 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -793,10 +793,7 @@ export class PortfolioService { historicalDataArray.push({ date, averagePrice: currentAveragePrice, - marketPrice: - historicalDataArray.length > 0 - ? marketPrice - : currentAveragePrice, + marketPrice, quantity: currentQuantity }); From 17e659857f4223882dcebe308d8314b833d9a550 Mon Sep 17 00:00:00 2001 From: bptrgx <47859535+bptrgx@users.noreply.github.com> Date: Fri, 30 May 2025 21:29:10 +0200 Subject: [PATCH 4/5] if the initial transaction has a null price, use the market price as initial value instead of the transaction price --- .../portfolio/calculator/roai/portfolio-calculator.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts index 2d6afab99..eddd938b6 100644 --- a/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/roai/portfolio-calculator.ts @@ -554,6 +554,16 @@ export class RoaiPortfolioCalculator extends PortfolioCalculator { initialValueWithCurrencyEffect = transactionInvestmentWithCurrencyEffect; + } else if ( + order.quantity.gt(0) && + ['BUY', 'SELL'].includes(order.type) && + !order.itemType + ) { + initialValue = order.quantity.mul(marketPriceInBaseCurrency); + + initialValueWithCurrencyEffect = order.quantity.mul( + marketPriceInBaseCurrencyWithCurrencyEffect + ); } } From 1c56d9a644430326e1b0bc0bd4b89e166bce9332 Mon Sep 17 00:00:00 2001 From: bptrgx <47859535+bptrgx@users.noreply.github.com> Date: Fri, 30 May 2025 21:30:06 +0200 Subject: [PATCH 5/5] Holding detail dialog: show null average unit price when held quantity of the asset is not null --- .../holding-detail-dialog.component.ts | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts index 028866009..65d77cd57 100644 --- a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts +++ b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts @@ -275,11 +275,13 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit { SymbolProfile?.userId === this.user?.id; this.historicalDataItems = historicalData.map( - ({ averagePrice, date, marketPrice }) => { - this.benchmarkDataItems.push({ - date, - value: averagePrice - }); + ({ averagePrice, date, marketPrice, quantity }) => { + if (quantity) { + this.benchmarkDataItems.push({ + date, + value: averagePrice + }); + } return { date, @@ -427,15 +429,6 @@ export class GfHoldingDetailDialogComponent implements OnDestroy, OnInit { this.benchmarkDataItems[0].value = this.averagePrice; } - this.benchmarkDataItems = this.benchmarkDataItems.map( - ({ date, value }) => { - return { - date, - value: value === 0 ? null : value - }; - } - ); - if (this.hasPermissionToReadMarketDataOfOwnAssetProfile) { this.fetchMarketData(); }