diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e991d77e..cd7de4e76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Optimized the portfolio calculations by reusing date intervals +- Refactored the calculation of the allocations by market on the allocations page - Refactored the calculation of the allocations by market on the public page ### Fixed diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 7c11e4767..aa3d23644 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -13,7 +13,10 @@ import { ApiService } from '@ghostfolio/api/services/api/api.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ImpersonationService } from '@ghostfolio/api/services/impersonation/impersonation.service'; import { getIntervalFromDateRange } from '@ghostfolio/common/calculation-helper'; -import { HEADER_KEY_IMPERSONATION } from '@ghostfolio/common/config'; +import { + HEADER_KEY_IMPERSONATION, + UNKNOWN_KEY +} from '@ghostfolio/common/config'; import { PortfolioDetails, PortfolioDividends, @@ -95,7 +98,7 @@ export class PortfolioController { filterByTags }); - const { accounts, hasErrors, holdings, platforms, summary } = + const { accounts, hasErrors, holdings, markets, platforms, summary } = await this.portfolioService.getDetails({ dateRange, filters, @@ -162,6 +165,10 @@ export class PortfolioController { }) || isRestrictedView(this.request.user) ) { + Object.values(markets).forEach((market) => { + delete market.valueInBaseCurrency; + }); + portfolioSummary = nullifyValuesInObject(summary, [ 'cash', 'committedFunds', @@ -214,6 +221,26 @@ export class PortfolioController { hasError, holdings, platforms, + markets: hasDetails + ? markets + : { + [UNKNOWN_KEY]: { + id: UNKNOWN_KEY, + valueInPercentage: 1 + }, + developedMarkets: { + id: 'developedMarkets', + valueInPercentage: 0 + }, + emergingMarkets: { + id: 'emergingMarkets', + valueInPercentage: 0 + }, + otherMarkets: { + id: 'otherMarkets', + valueInPercentage: 0 + } + }, summary: portfolioSummary }; } diff --git a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts index 89b08ad95..d7502cbfa 100644 --- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts +++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts @@ -47,7 +47,7 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { public hasImpersonationId: boolean; public isLoading = false; public markets: { - [key in Market]: { name: string; value: number }; + [key in Market]: { id: Market; valueInPercentage: number }; }; public marketsAdvanced: { [key in MarketAdvanced]: { @@ -219,24 +219,6 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { value: 0 } }; - this.markets = { - [UNKNOWN_KEY]: { - name: UNKNOWN_KEY, - value: 0 - }, - developedMarkets: { - name: 'developedMarkets', - value: 0 - }, - emergingMarkets: { - name: 'emergingMarkets', - value: 0 - }, - otherMarkets: { - name: 'otherMarkets', - value: 0 - } - }; this.marketsAdvanced = { [UNKNOWN_KEY]: { id: UNKNOWN_KEY, @@ -318,6 +300,8 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { }; } + this.markets = this.portfolioDetails.markets; + for (const [symbol, position] of Object.entries( this.portfolioDetails.holdings )) { @@ -348,22 +332,6 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { // Prepare analysis data by continents, countries, holdings and sectors except for liquidity if (position.countries.length > 0) { - this.markets.developedMarkets.value += - position.markets.developedMarkets * - (isNumber(position.valueInBaseCurrency) - ? position.valueInBaseCurrency - : position.valueInPercentage); - this.markets.emergingMarkets.value += - position.markets.emergingMarkets * - (isNumber(position.valueInBaseCurrency) - ? position.valueInBaseCurrency - : position.valueInPercentage); - this.markets.otherMarkets.value += - position.markets.otherMarkets * - (isNumber(position.valueInBaseCurrency) - ? position.valueInBaseCurrency - : position.valueInPercentage); - this.marketsAdvanced.asiaPacific.value += position.marketsAdvanced.asiaPacific * (isNumber(position.valueInBaseCurrency) @@ -440,12 +408,6 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { ? this.portfolioDetails.holdings[symbol].valueInBaseCurrency : this.portfolioDetails.holdings[symbol].valueInPercentage; - this.markets[UNKNOWN_KEY].value += isNumber( - position.valueInBaseCurrency - ) - ? this.portfolioDetails.holdings[symbol].valueInBaseCurrency - : this.portfolioDetails.holdings[symbol].valueInPercentage; - this.marketsAdvanced[UNKNOWN_KEY].value += isNumber( position.valueInBaseCurrency ) @@ -538,21 +500,6 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { }; } - const marketsTotal = - this.markets.developedMarkets.value + - this.markets.emergingMarkets.value + - this.markets.otherMarkets.value + - this.markets[UNKNOWN_KEY].value; - - this.markets.developedMarkets.value = - this.markets.developedMarkets.value / marketsTotal; - this.markets.emergingMarkets.value = - this.markets.emergingMarkets.value / marketsTotal; - this.markets.otherMarkets.value = - this.markets.otherMarkets.value / marketsTotal; - this.markets[UNKNOWN_KEY].value = - this.markets[UNKNOWN_KEY].value / marketsTotal; - this.topHoldings = Object.values(this.topHoldingsMap) .map(({ name, value }) => { if (this.hasImpersonationId || this.user.settings.isRestrictedView) { diff --git a/apps/client/src/app/pages/portfolio/allocations/allocations-page.html b/apps/client/src/app/pages/portfolio/allocations/allocations-page.html index 9b855592d..3431501f5 100644 --- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.html +++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.html @@ -218,7 +218,7 @@ i18n size="large" [isPercent]="true" - [value]="markets?.developedMarkets?.value" + [value]="markets?.developedMarkets?.valueInPercentage" >Developed Markets @@ -227,7 +227,7 @@ i18n size="large" [isPercent]="true" - [value]="markets?.emergingMarkets?.value" + [value]="markets?.emergingMarkets?.valueInPercentage" >Emerging Markets @@ -236,17 +236,17 @@ i18n size="large" [isPercent]="true" - [value]="markets?.otherMarkets?.value" + [value]="markets?.otherMarkets?.valueInPercentage" >Other Markets - @if (markets?.[UNKNOWN_KEY]?.value > 0) { + @if (markets?.[UNKNOWN_KEY]?.valueInPercentage > 0) {
No data available
diff --git a/libs/common/src/lib/interfaces/portfolio-details.interface.ts b/libs/common/src/lib/interfaces/portfolio-details.interface.ts index 2e9426936..711ae424f 100644 --- a/libs/common/src/lib/interfaces/portfolio-details.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-details.interface.ts @@ -18,7 +18,7 @@ export interface PortfolioDetails { markets?: { [key in Market]: { id: Market; - valueInBaseCurrency: number; + valueInBaseCurrency?: number; valueInPercentage: number; }; };