|
|
@ -33,6 +33,7 @@ import { |
|
|
import { |
|
|
import { |
|
|
DEFAULT_CURRENCY, |
|
|
DEFAULT_CURRENCY, |
|
|
DEFAULT_DATE_RANGE, |
|
|
DEFAULT_DATE_RANGE, |
|
|
|
|
|
DEFAULT_LANGUAGE_CODE, |
|
|
TAG_ID_DRAFT, |
|
|
TAG_ID_DRAFT, |
|
|
TAG_ID_EMERGENCY_FUND, |
|
|
TAG_ID_EMERGENCY_FUND, |
|
|
TAG_ID_EXCLUDE_FROM_ANALYSIS, |
|
|
TAG_ID_EXCLUDE_FROM_ANALYSIS, |
|
|
@ -1288,6 +1289,8 @@ export class PortfolioService { |
|
|
userSettings: this.request.user.settings.settings as UserSettings |
|
|
userSettings: this.request.user.settings.settings as UserSettings |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
const languageCode = userSettings.language ?? DEFAULT_LANGUAGE_CODE; |
|
|
|
|
|
|
|
|
const { accounts, holdings, markets, marketsAdvanced, summary } = |
|
|
const { accounts, holdings, markets, marketsAdvanced, summary } = |
|
|
await this.getDetails({ |
|
|
await this.getDetails({ |
|
|
user, |
|
|
user, |
|
|
@ -1330,8 +1333,8 @@ export class PortfolioService { |
|
|
{ |
|
|
{ |
|
|
key: 'liquidity', |
|
|
key: 'liquidity', |
|
|
name: this.i18nService.getTranslation({ |
|
|
name: this.i18nService.getTranslation({ |
|
|
id: 'rule.liquidity.category', |
|
|
languageCode, |
|
|
languageCode: userSettings.language |
|
|
id: 'rule.liquidity.category' |
|
|
}), |
|
|
}), |
|
|
rules: await this.rulesService.evaluate( |
|
|
rules: await this.rulesService.evaluate( |
|
|
[ |
|
|
[ |
|
|
@ -1339,7 +1342,7 @@ export class PortfolioService { |
|
|
this.exchangeRateDataService, |
|
|
this.exchangeRateDataService, |
|
|
this.i18nService, |
|
|
this.i18nService, |
|
|
summary.cash, |
|
|
summary.cash, |
|
|
userSettings.language |
|
|
languageCode |
|
|
) |
|
|
) |
|
|
], |
|
|
], |
|
|
userSettings |
|
|
userSettings |
|
|
@ -1348,15 +1351,15 @@ export class PortfolioService { |
|
|
{ |
|
|
{ |
|
|
key: 'emergencyFund', |
|
|
key: 'emergencyFund', |
|
|
name: this.i18nService.getTranslation({ |
|
|
name: this.i18nService.getTranslation({ |
|
|
id: 'rule.emergencyFund.category', |
|
|
languageCode, |
|
|
languageCode: userSettings.language |
|
|
id: 'rule.emergencyFund.category' |
|
|
}), |
|
|
}), |
|
|
rules: await this.rulesService.evaluate( |
|
|
rules: await this.rulesService.evaluate( |
|
|
[ |
|
|
[ |
|
|
new EmergencyFundSetup( |
|
|
new EmergencyFundSetup( |
|
|
this.exchangeRateDataService, |
|
|
this.exchangeRateDataService, |
|
|
this.i18nService, |
|
|
this.i18nService, |
|
|
userSettings.language, |
|
|
languageCode, |
|
|
totalEmergencyFundInBaseCurrency |
|
|
totalEmergencyFundInBaseCurrency |
|
|
), |
|
|
), |
|
|
// The coverage is only meaningful once an emergency fund has been
|
|
|
// The coverage is only meaningful once an emergency fund has been
|
|
|
@ -1366,7 +1369,7 @@ export class PortfolioService { |
|
|
new EmergencyFundCoverage( |
|
|
new EmergencyFundCoverage( |
|
|
this.exchangeRateDataService, |
|
|
this.exchangeRateDataService, |
|
|
this.i18nService, |
|
|
this.i18nService, |
|
|
userSettings.language, |
|
|
languageCode, |
|
|
emergencyFundInBaseCurrency, |
|
|
emergencyFundInBaseCurrency, |
|
|
emergencyFundHoldingsValueInBaseCurrency, |
|
|
emergencyFundHoldingsValueInBaseCurrency, |
|
|
cashBalanceInBaseCurrency |
|
|
cashBalanceInBaseCurrency |
|
|
@ -1380,8 +1383,8 @@ export class PortfolioService { |
|
|
{ |
|
|
{ |
|
|
key: 'currencyClusterRisk', |
|
|
key: 'currencyClusterRisk', |
|
|
name: this.i18nService.getTranslation({ |
|
|
name: this.i18nService.getTranslation({ |
|
|
id: 'rule.currencyClusterRisk.category', |
|
|
languageCode, |
|
|
languageCode: userSettings.language |
|
|
id: 'rule.currencyClusterRisk.category' |
|
|
}), |
|
|
}), |
|
|
rules: hasOpenHoldings |
|
|
rules: hasOpenHoldings |
|
|
? await this.rulesService.evaluate( |
|
|
? await this.rulesService.evaluate( |
|
|
@ -1390,13 +1393,13 @@ export class PortfolioService { |
|
|
this.exchangeRateDataService, |
|
|
this.exchangeRateDataService, |
|
|
this.i18nService, |
|
|
this.i18nService, |
|
|
holdings, |
|
|
holdings, |
|
|
userSettings.language |
|
|
languageCode |
|
|
), |
|
|
), |
|
|
new CurrencyClusterRiskCurrentInvestment( |
|
|
new CurrencyClusterRiskCurrentInvestment( |
|
|
this.exchangeRateDataService, |
|
|
this.exchangeRateDataService, |
|
|
this.i18nService, |
|
|
this.i18nService, |
|
|
holdings, |
|
|
holdings, |
|
|
userSettings.language |
|
|
languageCode |
|
|
) |
|
|
) |
|
|
], |
|
|
], |
|
|
userSettings |
|
|
userSettings |
|
|
@ -1406,8 +1409,8 @@ export class PortfolioService { |
|
|
{ |
|
|
{ |
|
|
key: 'assetClassClusterRisk', |
|
|
key: 'assetClassClusterRisk', |
|
|
name: this.i18nService.getTranslation({ |
|
|
name: this.i18nService.getTranslation({ |
|
|
id: 'rule.assetClassClusterRisk.category', |
|
|
languageCode, |
|
|
languageCode: userSettings.language |
|
|
id: 'rule.assetClassClusterRisk.category' |
|
|
}), |
|
|
}), |
|
|
rules: hasOpenHoldings |
|
|
rules: hasOpenHoldings |
|
|
? await this.rulesService.evaluate( |
|
|
? await this.rulesService.evaluate( |
|
|
@ -1415,13 +1418,13 @@ export class PortfolioService { |
|
|
new AssetClassClusterRiskEquity( |
|
|
new AssetClassClusterRiskEquity( |
|
|
this.exchangeRateDataService, |
|
|
this.exchangeRateDataService, |
|
|
this.i18nService, |
|
|
this.i18nService, |
|
|
userSettings.language, |
|
|
languageCode, |
|
|
holdings |
|
|
holdings |
|
|
), |
|
|
), |
|
|
new AssetClassClusterRiskFixedIncome( |
|
|
new AssetClassClusterRiskFixedIncome( |
|
|
this.exchangeRateDataService, |
|
|
this.exchangeRateDataService, |
|
|
this.i18nService, |
|
|
this.i18nService, |
|
|
userSettings.language, |
|
|
languageCode, |
|
|
holdings |
|
|
holdings |
|
|
) |
|
|
) |
|
|
], |
|
|
], |
|
|
@ -1432,8 +1435,8 @@ export class PortfolioService { |
|
|
{ |
|
|
{ |
|
|
key: 'accountClusterRisk', |
|
|
key: 'accountClusterRisk', |
|
|
name: this.i18nService.getTranslation({ |
|
|
name: this.i18nService.getTranslation({ |
|
|
id: 'rule.accountClusterRisk.category', |
|
|
languageCode, |
|
|
languageCode: userSettings.language |
|
|
id: 'rule.accountClusterRisk.category' |
|
|
}), |
|
|
}), |
|
|
rules: |
|
|
rules: |
|
|
summary.activityCount > 0 |
|
|
summary.activityCount > 0 |
|
|
@ -1442,13 +1445,13 @@ export class PortfolioService { |
|
|
new AccountClusterRiskCurrentInvestment( |
|
|
new AccountClusterRiskCurrentInvestment( |
|
|
this.exchangeRateDataService, |
|
|
this.exchangeRateDataService, |
|
|
this.i18nService, |
|
|
this.i18nService, |
|
|
userSettings.language, |
|
|
languageCode, |
|
|
accounts |
|
|
accounts |
|
|
), |
|
|
), |
|
|
new AccountClusterRiskSingleAccount( |
|
|
new AccountClusterRiskSingleAccount( |
|
|
this.exchangeRateDataService, |
|
|
this.exchangeRateDataService, |
|
|
this.i18nService, |
|
|
this.i18nService, |
|
|
userSettings.language, |
|
|
languageCode, |
|
|
accounts |
|
|
accounts |
|
|
) |
|
|
) |
|
|
], |
|
|
], |
|
|
@ -1459,8 +1462,8 @@ export class PortfolioService { |
|
|
{ |
|
|
{ |
|
|
key: 'economicMarketClusterRisk', |
|
|
key: 'economicMarketClusterRisk', |
|
|
name: this.i18nService.getTranslation({ |
|
|
name: this.i18nService.getTranslation({ |
|
|
id: 'rule.economicMarketClusterRisk.category', |
|
|
languageCode, |
|
|
languageCode: userSettings.language |
|
|
id: 'rule.economicMarketClusterRisk.category' |
|
|
}), |
|
|
}), |
|
|
rules: hasOpenHoldings |
|
|
rules: hasOpenHoldings |
|
|
? await this.rulesService.evaluate( |
|
|
? await this.rulesService.evaluate( |
|
|
@ -1470,14 +1473,14 @@ export class PortfolioService { |
|
|
this.i18nService, |
|
|
this.i18nService, |
|
|
marketsTotalInBaseCurrency, |
|
|
marketsTotalInBaseCurrency, |
|
|
markets.developedMarkets.valueInBaseCurrency, |
|
|
markets.developedMarkets.valueInBaseCurrency, |
|
|
userSettings.language |
|
|
languageCode |
|
|
), |
|
|
), |
|
|
new EconomicMarketClusterRiskEmergingMarkets( |
|
|
new EconomicMarketClusterRiskEmergingMarkets( |
|
|
this.exchangeRateDataService, |
|
|
this.exchangeRateDataService, |
|
|
this.i18nService, |
|
|
this.i18nService, |
|
|
marketsTotalInBaseCurrency, |
|
|
marketsTotalInBaseCurrency, |
|
|
markets.emergingMarkets.valueInBaseCurrency, |
|
|
markets.emergingMarkets.valueInBaseCurrency, |
|
|
userSettings.language |
|
|
languageCode |
|
|
) |
|
|
) |
|
|
], |
|
|
], |
|
|
userSettings |
|
|
userSettings |
|
|
@ -1487,8 +1490,8 @@ export class PortfolioService { |
|
|
{ |
|
|
{ |
|
|
key: 'regionalMarketClusterRisk', |
|
|
key: 'regionalMarketClusterRisk', |
|
|
name: this.i18nService.getTranslation({ |
|
|
name: this.i18nService.getTranslation({ |
|
|
id: 'rule.regionalMarketClusterRisk.category', |
|
|
languageCode, |
|
|
languageCode: userSettings.language |
|
|
id: 'rule.regionalMarketClusterRisk.category' |
|
|
}), |
|
|
}), |
|
|
rules: hasOpenHoldings |
|
|
rules: hasOpenHoldings |
|
|
? await this.rulesService.evaluate( |
|
|
? await this.rulesService.evaluate( |
|
|
@ -1496,35 +1499,35 @@ export class PortfolioService { |
|
|
new RegionalMarketClusterRiskAsiaPacific( |
|
|
new RegionalMarketClusterRiskAsiaPacific( |
|
|
this.exchangeRateDataService, |
|
|
this.exchangeRateDataService, |
|
|
this.i18nService, |
|
|
this.i18nService, |
|
|
userSettings.language, |
|
|
languageCode, |
|
|
marketsAdvancedTotalInBaseCurrency, |
|
|
marketsAdvancedTotalInBaseCurrency, |
|
|
marketsAdvanced.asiaPacific.valueInBaseCurrency |
|
|
marketsAdvanced.asiaPacific.valueInBaseCurrency |
|
|
), |
|
|
), |
|
|
new RegionalMarketClusterRiskEmergingMarkets( |
|
|
new RegionalMarketClusterRiskEmergingMarkets( |
|
|
this.exchangeRateDataService, |
|
|
this.exchangeRateDataService, |
|
|
this.i18nService, |
|
|
this.i18nService, |
|
|
userSettings.language, |
|
|
languageCode, |
|
|
marketsAdvancedTotalInBaseCurrency, |
|
|
marketsAdvancedTotalInBaseCurrency, |
|
|
marketsAdvanced.emergingMarkets.valueInBaseCurrency |
|
|
marketsAdvanced.emergingMarkets.valueInBaseCurrency |
|
|
), |
|
|
), |
|
|
new RegionalMarketClusterRiskEurope( |
|
|
new RegionalMarketClusterRiskEurope( |
|
|
this.exchangeRateDataService, |
|
|
this.exchangeRateDataService, |
|
|
this.i18nService, |
|
|
this.i18nService, |
|
|
userSettings.language, |
|
|
languageCode, |
|
|
marketsAdvancedTotalInBaseCurrency, |
|
|
marketsAdvancedTotalInBaseCurrency, |
|
|
marketsAdvanced.europe.valueInBaseCurrency |
|
|
marketsAdvanced.europe.valueInBaseCurrency |
|
|
), |
|
|
), |
|
|
new RegionalMarketClusterRiskJapan( |
|
|
new RegionalMarketClusterRiskJapan( |
|
|
this.exchangeRateDataService, |
|
|
this.exchangeRateDataService, |
|
|
this.i18nService, |
|
|
this.i18nService, |
|
|
userSettings.language, |
|
|
languageCode, |
|
|
marketsAdvancedTotalInBaseCurrency, |
|
|
marketsAdvancedTotalInBaseCurrency, |
|
|
marketsAdvanced.japan.valueInBaseCurrency |
|
|
marketsAdvanced.japan.valueInBaseCurrency |
|
|
), |
|
|
), |
|
|
new RegionalMarketClusterRiskNorthAmerica( |
|
|
new RegionalMarketClusterRiskNorthAmerica( |
|
|
this.exchangeRateDataService, |
|
|
this.exchangeRateDataService, |
|
|
this.i18nService, |
|
|
this.i18nService, |
|
|
userSettings.language, |
|
|
languageCode, |
|
|
marketsAdvancedTotalInBaseCurrency, |
|
|
marketsAdvancedTotalInBaseCurrency, |
|
|
marketsAdvanced.northAmerica.valueInBaseCurrency |
|
|
marketsAdvanced.northAmerica.valueInBaseCurrency |
|
|
) |
|
|
) |
|
|
@ -1536,15 +1539,15 @@ export class PortfolioService { |
|
|
{ |
|
|
{ |
|
|
key: 'fees', |
|
|
key: 'fees', |
|
|
name: this.i18nService.getTranslation({ |
|
|
name: this.i18nService.getTranslation({ |
|
|
id: 'rule.fees.category', |
|
|
languageCode, |
|
|
languageCode: userSettings.language |
|
|
id: 'rule.fees.category' |
|
|
}), |
|
|
}), |
|
|
rules: await this.rulesService.evaluate( |
|
|
rules: await this.rulesService.evaluate( |
|
|
[ |
|
|
[ |
|
|
new FeeRatioTotalInvestmentVolume( |
|
|
new FeeRatioTotalInvestmentVolume( |
|
|
this.exchangeRateDataService, |
|
|
this.exchangeRateDataService, |
|
|
this.i18nService, |
|
|
this.i18nService, |
|
|
userSettings.language, |
|
|
languageCode, |
|
|
summary.totalBuy + summary.totalSell, |
|
|
summary.totalBuy + summary.totalSell, |
|
|
summary.fees |
|
|
summary.fees |
|
|
) |
|
|
) |
|
|
|