|
|
@ -33,6 +33,7 @@ import { |
|
|
} from '@ghostfolio/common/calculation-helper'; |
|
|
} from '@ghostfolio/common/calculation-helper'; |
|
|
import { |
|
|
import { |
|
|
DEFAULT_CURRENCY, |
|
|
DEFAULT_CURRENCY, |
|
|
|
|
|
DEFAULT_LANGUAGE_CODE, |
|
|
TAG_ID_EMERGENCY_FUND, |
|
|
TAG_ID_EMERGENCY_FUND, |
|
|
TAG_ID_EXCLUDE_FROM_ANALYSIS, |
|
|
TAG_ID_EXCLUDE_FROM_ANALYSIS, |
|
|
UNKNOWN_KEY |
|
|
UNKNOWN_KEY |
|
|
@ -1235,7 +1236,10 @@ export class PortfolioService { |
|
|
const categories: PortfolioReportResponse['xRay']['categories'] = [ |
|
|
const categories: PortfolioReportResponse['xRay']['categories'] = [ |
|
|
{ |
|
|
{ |
|
|
key: 'accountClusterRisk', |
|
|
key: 'accountClusterRisk', |
|
|
name: 'accountClusterRisk', |
|
|
name: this.i18nService.getTranslation({ |
|
|
|
|
|
id: 'rule.accountClusterRisk.category', |
|
|
|
|
|
languageCode: userSettings.language || DEFAULT_LANGUAGE_CODE |
|
|
|
|
|
}), |
|
|
rules: |
|
|
rules: |
|
|
summary.activityCount > 0 |
|
|
summary.activityCount > 0 |
|
|
? await this.rulesService.evaluate( |
|
|
? await this.rulesService.evaluate( |
|
|
@ -1259,7 +1263,10 @@ export class PortfolioService { |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
key: 'assetClassClusterRisk', |
|
|
key: 'assetClassClusterRisk', |
|
|
name: 'assetClassClusterRisk', |
|
|
name: this.i18nService.getTranslation({ |
|
|
|
|
|
id: 'rule.assetClassClusterRisk.category', |
|
|
|
|
|
languageCode: userSettings.language || DEFAULT_LANGUAGE_CODE |
|
|
|
|
|
}), |
|
|
rules: |
|
|
rules: |
|
|
summary.activityCount > 0 |
|
|
summary.activityCount > 0 |
|
|
? await this.rulesService.evaluate( |
|
|
? await this.rulesService.evaluate( |
|
|
@ -1283,7 +1290,10 @@ export class PortfolioService { |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
key: 'currencyClusterRisk', |
|
|
key: 'currencyClusterRisk', |
|
|
name: 'currencyClusterRisk', |
|
|
name: this.i18nService.getTranslation({ |
|
|
|
|
|
id: 'rule.currencyClusterRisk.category', |
|
|
|
|
|
languageCode: userSettings.language || DEFAULT_LANGUAGE_CODE |
|
|
|
|
|
}), |
|
|
rules: |
|
|
rules: |
|
|
summary.activityCount > 0 |
|
|
summary.activityCount > 0 |
|
|
? await this.rulesService.evaluate( |
|
|
? await this.rulesService.evaluate( |
|
|
@ -1307,7 +1317,10 @@ export class PortfolioService { |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
key: 'economicMarketClusterRisk', |
|
|
key: 'economicMarketClusterRisk', |
|
|
name: 'economicMarketClusterRisk', |
|
|
name: this.i18nService.getTranslation({ |
|
|
|
|
|
id: 'rule.economicMarketClusterRisk.category', |
|
|
|
|
|
languageCode: userSettings.language || DEFAULT_LANGUAGE_CODE |
|
|
|
|
|
}), |
|
|
rules: |
|
|
rules: |
|
|
summary.activityCount > 0 |
|
|
summary.activityCount > 0 |
|
|
? await this.rulesService.evaluate( |
|
|
? await this.rulesService.evaluate( |
|
|
@ -1333,7 +1346,10 @@ export class PortfolioService { |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
key: 'emergencyFund', |
|
|
key: 'emergencyFund', |
|
|
name: 'emergencyFund', |
|
|
name: this.i18nService.getTranslation({ |
|
|
|
|
|
id: 'rule.emergencyFund.category', |
|
|
|
|
|
languageCode: userSettings.language || DEFAULT_LANGUAGE_CODE |
|
|
|
|
|
}), |
|
|
rules: await this.rulesService.evaluate( |
|
|
rules: await this.rulesService.evaluate( |
|
|
[ |
|
|
[ |
|
|
new EmergencyFundSetup( |
|
|
new EmergencyFundSetup( |
|
|
@ -1352,7 +1368,10 @@ export class PortfolioService { |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
key: 'fees', |
|
|
key: 'fees', |
|
|
name: 'fees', |
|
|
name: this.i18nService.getTranslation({ |
|
|
|
|
|
id: 'rule.fees.category', |
|
|
|
|
|
languageCode: userSettings.language || DEFAULT_LANGUAGE_CODE |
|
|
|
|
|
}), |
|
|
rules: await this.rulesService.evaluate( |
|
|
rules: await this.rulesService.evaluate( |
|
|
[ |
|
|
[ |
|
|
new FeeRatioInitialInvestment( |
|
|
new FeeRatioInitialInvestment( |
|
|
@ -1368,7 +1387,10 @@ export class PortfolioService { |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
key: 'liquidity', |
|
|
key: 'liquidity', |
|
|
name: 'liquidity', |
|
|
name: this.i18nService.getTranslation({ |
|
|
|
|
|
id: 'rule.liquidity.category', |
|
|
|
|
|
languageCode: userSettings.language || DEFAULT_LANGUAGE_CODE |
|
|
|
|
|
}), |
|
|
rules: await this.rulesService.evaluate( |
|
|
rules: await this.rulesService.evaluate( |
|
|
[ |
|
|
[ |
|
|
new BuyingPower( |
|
|
new BuyingPower( |
|
|
@ -1383,7 +1405,10 @@ export class PortfolioService { |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
key: 'regionalMarketClusterRisk', |
|
|
key: 'regionalMarketClusterRisk', |
|
|
name: 'regionalMarketClusterRisk', |
|
|
name: this.i18nService.getTranslation({ |
|
|
|
|
|
id: 'rule.regionalMarketClusterRisk.category', |
|
|
|
|
|
languageCode: userSettings.language || DEFAULT_LANGUAGE_CODE |
|
|
|
|
|
}), |
|
|
rules: |
|
|
rules: |
|
|
summary.activityCount > 0 |
|
|
summary.activityCount > 0 |
|
|
? await this.rulesService.evaluate( |
|
|
? await this.rulesService.evaluate( |
|
|
@ -1434,7 +1459,9 @@ export class PortfolioService { |
|
|
xRay: { |
|
|
xRay: { |
|
|
categories, |
|
|
categories, |
|
|
statistics: this.getReportStatistics( |
|
|
statistics: this.getReportStatistics( |
|
|
categories.flatMap(({ rules }) => rules ?? []) |
|
|
categories.flatMap(({ rules }) => { |
|
|
|
|
|
return rules ?? []; |
|
|
|
|
|
}) |
|
|
) |
|
|
) |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|