Browse Source

Bugfix/static portfolio analysis rules for portfolio with no holdings (#7466)

* Fix static portfolio analysis rules for portfolio with no holdings

* Update changelog
pull/7481/head^2
Thomas Kaul 1 week ago
committed by GitHub
parent
commit
1770350516
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 14
      CHANGELOG.md
  2. 208
      apps/api/src/app/portfolio/portfolio.service.ts

14
CHANGELOG.md

@ -14,6 +14,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Improved the performance of the property service by caching the properties in memory - Improved the performance of the property service by caching the properties in memory
- Improved the language localization for German (`de`) - Improved the language localization for German (`de`)
### Fixed
- Fixed the static portfolio analysis rule for a portfolio with no holdings: _Asset Class Cluster Risks_ (Equity)
- Fixed the static portfolio analysis rule for a portfolio with no holdings: _Asset Class Cluster Risks_ (Fixed Income)
- Fixed the static portfolio analysis rule for a portfolio with no holdings: _Currency Cluster Risks_ (Investment)
- Fixed the static portfolio analysis rule for a portfolio with no holdings: _Currency Cluster Risks_ (Investment: Base Currency)
- Fixed the static portfolio analysis rule for a portfolio with no holdings: _Economic Market Cluster Risks_ (Developed Markets)
- Fixed the static portfolio analysis rule for a portfolio with no holdings: _Economic Market Cluster Risks_ (Emerging Markets)
- Fixed the static portfolio analysis rule for a portfolio with no holdings: _Regional Market Cluster Risks_ (Asia-Pacific)
- Fixed the static portfolio analysis rule for a portfolio with no holdings: _Regional Market Cluster Risks_ (Emerging Markets)
- Fixed the static portfolio analysis rule for a portfolio with no holdings: _Regional Market Cluster Risks_ (Europe)
- Fixed the static portfolio analysis rule for a portfolio with no holdings: _Regional Market Cluster Risks_ (Japan)
- Fixed the static portfolio analysis rule for a portfolio with no holdings: _Regional Market Cluster Risks_ (North America)
## 3.37.0 - 2026-07-30 ## 3.37.0 - 2026-07-30
### Added ### Added

208
apps/api/src/app/portfolio/portfolio.service.ts

@ -1126,6 +1126,8 @@ export class PortfolioService {
withSummary: true withSummary: true
}); });
const hasOpenHoldings = Object.keys(holdings).length > 0;
const marketsAdvancedTotalInBaseCurrency = getSum( const marketsAdvancedTotalInBaseCurrency = getSum(
Object.values(marketsAdvanced).map(({ valueInBaseCurrency }) => { Object.values(marketsAdvanced).map(({ valueInBaseCurrency }) => {
return new Big(valueInBaseCurrency); return new Big(valueInBaseCurrency);
@ -1185,26 +1187,25 @@ export class PortfolioService {
id: 'rule.currencyClusterRisk.category', id: 'rule.currencyClusterRisk.category',
languageCode: userSettings.language languageCode: userSettings.language
}), }),
rules: rules: hasOpenHoldings
summary.activityCount > 0 ? await this.rulesService.evaluate(
? await this.rulesService.evaluate( [
[ new CurrencyClusterRiskBaseCurrencyCurrentInvestment(
new CurrencyClusterRiskBaseCurrencyCurrentInvestment( this.exchangeRateDataService,
this.exchangeRateDataService, this.i18nService,
this.i18nService, Object.values(holdings),
Object.values(holdings), userSettings.language
userSettings.language ),
), new CurrencyClusterRiskCurrentInvestment(
new CurrencyClusterRiskCurrentInvestment( this.exchangeRateDataService,
this.exchangeRateDataService, this.i18nService,
this.i18nService, Object.values(holdings),
Object.values(holdings), userSettings.language
userSettings.language )
) ],
], userSettings
userSettings )
) : undefined
: undefined
}, },
{ {
key: 'assetClassClusterRisk', key: 'assetClassClusterRisk',
@ -1212,26 +1213,25 @@ export class PortfolioService {
id: 'rule.assetClassClusterRisk.category', id: 'rule.assetClassClusterRisk.category',
languageCode: userSettings.language languageCode: userSettings.language
}), }),
rules: rules: hasOpenHoldings
summary.activityCount > 0 ? await this.rulesService.evaluate(
? await this.rulesService.evaluate( [
[ new AssetClassClusterRiskEquity(
new AssetClassClusterRiskEquity( this.exchangeRateDataService,
this.exchangeRateDataService, this.i18nService,
this.i18nService, userSettings.language,
userSettings.language, Object.values(holdings)
Object.values(holdings) ),
), new AssetClassClusterRiskFixedIncome(
new AssetClassClusterRiskFixedIncome( this.exchangeRateDataService,
this.exchangeRateDataService, this.i18nService,
this.i18nService, userSettings.language,
userSettings.language, Object.values(holdings)
Object.values(holdings) )
) ],
], userSettings
userSettings )
) : undefined
: undefined
}, },
{ {
key: 'accountClusterRisk', key: 'accountClusterRisk',
@ -1266,28 +1266,27 @@ export class PortfolioService {
id: 'rule.economicMarketClusterRisk.category', id: 'rule.economicMarketClusterRisk.category',
languageCode: userSettings.language languageCode: userSettings.language
}), }),
rules: rules: hasOpenHoldings
summary.activityCount > 0 ? await this.rulesService.evaluate(
? await this.rulesService.evaluate( [
[ new EconomicMarketClusterRiskDevelopedMarkets(
new EconomicMarketClusterRiskDevelopedMarkets( this.exchangeRateDataService,
this.exchangeRateDataService, this.i18nService,
this.i18nService, marketsTotalInBaseCurrency,
marketsTotalInBaseCurrency, markets.developedMarkets.valueInBaseCurrency,
markets.developedMarkets.valueInBaseCurrency, userSettings.language
userSettings.language ),
), new EconomicMarketClusterRiskEmergingMarkets(
new EconomicMarketClusterRiskEmergingMarkets( this.exchangeRateDataService,
this.exchangeRateDataService, this.i18nService,
this.i18nService, marketsTotalInBaseCurrency,
marketsTotalInBaseCurrency, markets.emergingMarkets.valueInBaseCurrency,
markets.emergingMarkets.valueInBaseCurrency, userSettings.language
userSettings.language )
) ],
], userSettings
userSettings )
) : undefined
: undefined
}, },
{ {
key: 'regionalMarketClusterRisk', key: 'regionalMarketClusterRisk',
@ -1295,49 +1294,48 @@ export class PortfolioService {
id: 'rule.regionalMarketClusterRisk.category', id: 'rule.regionalMarketClusterRisk.category',
languageCode: userSettings.language languageCode: userSettings.language
}), }),
rules: rules: hasOpenHoldings
summary.activityCount > 0 ? await this.rulesService.evaluate(
? await this.rulesService.evaluate( [
[ new RegionalMarketClusterRiskAsiaPacific(
new RegionalMarketClusterRiskAsiaPacific( this.exchangeRateDataService,
this.exchangeRateDataService, this.i18nService,
this.i18nService, userSettings.language,
userSettings.language, marketsAdvancedTotalInBaseCurrency,
marketsAdvancedTotalInBaseCurrency, marketsAdvanced.asiaPacific.valueInBaseCurrency
marketsAdvanced.asiaPacific.valueInBaseCurrency ),
), new RegionalMarketClusterRiskEmergingMarkets(
new RegionalMarketClusterRiskEmergingMarkets( this.exchangeRateDataService,
this.exchangeRateDataService, this.i18nService,
this.i18nService, userSettings.language,
userSettings.language, marketsAdvancedTotalInBaseCurrency,
marketsAdvancedTotalInBaseCurrency, marketsAdvanced.emergingMarkets.valueInBaseCurrency
marketsAdvanced.emergingMarkets.valueInBaseCurrency ),
), new RegionalMarketClusterRiskEurope(
new RegionalMarketClusterRiskEurope( this.exchangeRateDataService,
this.exchangeRateDataService, this.i18nService,
this.i18nService, userSettings.language,
userSettings.language, marketsAdvancedTotalInBaseCurrency,
marketsAdvancedTotalInBaseCurrency, marketsAdvanced.europe.valueInBaseCurrency
marketsAdvanced.europe.valueInBaseCurrency ),
), new RegionalMarketClusterRiskJapan(
new RegionalMarketClusterRiskJapan( this.exchangeRateDataService,
this.exchangeRateDataService, this.i18nService,
this.i18nService, userSettings.language,
userSettings.language, marketsAdvancedTotalInBaseCurrency,
marketsAdvancedTotalInBaseCurrency, marketsAdvanced.japan.valueInBaseCurrency
marketsAdvanced.japan.valueInBaseCurrency ),
), new RegionalMarketClusterRiskNorthAmerica(
new RegionalMarketClusterRiskNorthAmerica( this.exchangeRateDataService,
this.exchangeRateDataService, this.i18nService,
this.i18nService, userSettings.language,
userSettings.language, marketsAdvancedTotalInBaseCurrency,
marketsAdvancedTotalInBaseCurrency, marketsAdvanced.northAmerica.valueInBaseCurrency
marketsAdvanced.northAmerica.valueInBaseCurrency )
) ],
], userSettings
userSettings )
) : undefined
: undefined
}, },
{ {
key: 'fees', key: 'fees',

Loading…
Cancel
Save