From cd71ed885274df68271efd8959218d33127321f8 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 27 Jul 2026 20:00:23 +0200 Subject: [PATCH] Exclude cash in base currency from portfolio performance calculation --- .../portfolio-summary.component.html | 196 ++++++++++-------- .../portfolio-summary.component.scss | 8 + .../portfolio-summary.component.ts | 27 ++- 3 files changed, 140 insertions(+), 91 deletions(-) diff --git a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html index 70b087ea31..3c1d3e9ad1 100644 --- a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html +++ b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html @@ -9,7 +9,7 @@ class="flex-nowrap px-3 py-1 row" [hidden]="summary?.activityCount === null" > -
+
{{ summary?.activityCount }} {summary?.activityCount, plural, =1 {activity} @@ -123,7 +123,7 @@
-
+
Net Performance
-
Cash
+
+ Cash + @if (!hasImpersonationId && summary?.totalValueInBaseCurrency > 0) { + + } +
-
-
- Buying Power - @if ( - !hasImpersonationId && - summary?.totalValueInBaseCurrency > 0 && - user?.settings?.isExperimentalFeatures - ) { + @if (isLoading || summary?.emergencyFund?.cash > 0) { +
+
Buying Power
+
- } +
-
- +
+
Emergency Fund
+
+ +
-
+ }
-
- Emergency Fund - @if ( - !hasImpersonationId && - summary?.totalValueInBaseCurrency > 0 && - user?.settings?.isExperimentalFeatures - ) { +
+ Holdings + @if (!hasImpersonationId && summary?.totalValueInBaseCurrency > 0) { }
-
- @if ( - hasPermissionToUpdateUserSettings && - !isLoading && - !user?.settings?.isRestrictedView && - user?.subscription?.type !== 'Basic' - ) { - - } - -
-
-
-
in Cash
-
-
in Holdings
-
- + @if (isLoading || summary?.emergencyFund?.assets > 0) { +
+
Emergency Fund
+
+ +
-
+ }
Excluded from Analysis - @if ( - !hasImpersonationId && - summary?.totalValueInBaseCurrency > 0 && - user?.settings?.isExperimentalFeatures - ) { + @if (!hasImpersonationId && summary?.totalValueInBaseCurrency > 0) {
-
+
Annualized Performance
@@ -368,6 +339,53 @@

+
+
+ Emergency Fund + @if (!hasImpersonationId && summary?.totalValueInBaseCurrency > 0) { + + } +
+
+ @if ( + hasPermissionToUpdateUserSettings && + !isLoading && + !user?.settings?.isRestrictedView && + user?.subscription?.type !== 'Basic' + ) { + + } + +
+
Interest
diff --git a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.scss b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.scss index 5d4e87f30f..6feaa22d1a 100644 --- a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.scss +++ b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.scss @@ -1,3 +1,11 @@ :host { display: block; + + .indent-1 { + margin-left: 1rem; + } + + .indent-2 { + margin-left: 2rem; + } } diff --git a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts index b1e32c6c36..5b3c0f46b8 100644 --- a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts +++ b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts @@ -21,6 +21,7 @@ import { ellipsisHorizontalCircleOutline, informationCircleOutline } from 'ionicons/icons'; +import { isNumber } from 'lodash'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, @@ -55,9 +56,10 @@ export class GfPortfolioSummaryComponent implements OnChanges { addIcons({ ellipsisHorizontalCircleOutline, informationCircleOutline }); } - protected get buyingPowerPercentage() { + protected get cashPercentage() { return this.summary?.totalValueInBaseCurrency - ? this.summary.cash / this.summary.totalValueInBaseCurrency + ? this.summary.totalCashInBaseCurrency / + this.summary.totalValueInBaseCurrency : 0; } @@ -75,6 +77,27 @@ export class GfPortfolioSummaryComponent implements OnChanges { : 0; } + protected get holdingsInBaseCurrency() { + if ( + !isNumber(this.summary?.currentValueInBaseCurrency) || + !isNumber(this.summary?.totalCashInBaseCurrency) + ) { + return null; + } + + return ( + this.summary.currentValueInBaseCurrency - + this.summary.totalCashInBaseCurrency + ); + } + + protected get holdingsPercentage() { + return this.summary?.totalValueInBaseCurrency && + isNumber(this.holdingsInBaseCurrency) + ? this.holdingsInBaseCurrency / this.summary.totalValueInBaseCurrency + : 0; + } + public ngOnChanges() { if (this.summary) { if (