import { Rule } from '@ghostfolio/api/models/rule'; import type { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import type { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; import type { PortfolioPosition, RuleSettings } from '@ghostfolio/common/interfaces'; export class CurrencyClusterRiskCurrentInvestment extends Rule { private holdings: PortfolioPosition[]; private i18nService: I18nService; public constructor({ exchangeRateDataService, holdings, i18nService, languageCode }: { exchangeRateDataService: ExchangeRateDataService; holdings: PortfolioPosition[]; i18nService: I18nService; languageCode: string; }) { super({ exchangeRateDataService, languageCode, key: 'CurrencyClusterRiskCurrentInvestment' }); this.holdings = holdings; this.i18nService = i18nService; } public evaluate(ruleSettings: Settings) { const holdingsGroupedByCurrency = this.groupCurrentHoldingsByAttribute( this.holdings, 'assetProfile.currency', ruleSettings.baseCurrency ); let maxItem = holdingsGroupedByCurrency[0]; let totalValue = 0; holdingsGroupedByCurrency.forEach((groupItem) => { // Calculate total value totalValue += groupItem.value; // Find maximum if (groupItem.value > maxItem.value) { maxItem = groupItem; } }); const maxValueRatio = maxItem?.value / totalValue || 0; if (maxValueRatio > ruleSettings.thresholdMax) { return { evaluation: this.i18nService.getTranslation({ id: 'rule.currencyClusterRiskCurrentInvestment.false', languageCode: this.getLanguageCode(), placeholders: { currency: maxItem.groupKey as string, maxValueRatio: (maxValueRatio * 100).toPrecision(3), thresholdMax: ruleSettings.thresholdMax * 100 } }), value: false }; } return { evaluation: this.i18nService.getTranslation({ id: 'rule.currencyClusterRiskCurrentInvestment.true', languageCode: this.getLanguageCode(), placeholders: { currency: maxItem.groupKey as string, maxValueRatio: (maxValueRatio * 100).toPrecision(3), thresholdMax: ruleSettings.thresholdMax * 100 } }), value: true }; } public getConfiguration() { return { threshold: { max: 1, min: 0, step: 0.01, unit: '%' }, thresholdMax: true }; } public getName() { return this.i18nService.getTranslation({ id: 'rule.currencyClusterRiskCurrentInvestment', languageCode: this.getLanguageCode() }); } } interface Settings extends RuleSettings { baseCurrency: string; thresholdMax: number; }