import { Currency } from '@prisma/client'; import { PortfolioPosition } from '@ghostfolio/common/interfaces'; import { ExchangeRateDataService } from 'apps/api/src/services/exchange-rate-data.service'; import { Rule } from '../../rule'; import { UserSettings } from '@ghostfolio/api/models/interfaces/user-settings.interface'; import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface'; export class CurrencyClusterRiskBaseCurrencyInitialInvestment extends Rule { public constructor(public exchangeRateDataService: ExchangeRateDataService) { super(exchangeRateDataService, { name: 'Initial Investment: Base Currency' }); } public evaluate( aPositions: { [symbol: string]: PortfolioPosition }, aFees: number, ruleSettings: Settings ) { const positionsGroupedByCurrency = this.groupPositionsByAttribute( aPositions, 'currency', ruleSettings.baseCurrency ); let maxItem = positionsGroupedByCurrency[0]; let totalInvestment = 0; positionsGroupedByCurrency.forEach((groupItem) => { // Calculate total investment totalInvestment += groupItem.investment; // Find maximum if (groupItem.investment > maxItem.investment) { maxItem = groupItem; } }); const baseCurrencyItem = positionsGroupedByCurrency.find((item) => { return item.groupKey === ruleSettings.baseCurrency; }); const baseCurrencyInvestmentRatio = baseCurrencyItem?.investment / totalInvestment || 0; if (maxItem.groupKey !== ruleSettings.baseCurrency) { return { evaluation: `The major part of your initial investment is not in your base currency (${( baseCurrencyInvestmentRatio * 100 ).toPrecision(3)}% in ${ruleSettings.baseCurrency})`, value: false }; } return { evaluation: `The major part of your initial investment is in your base currency (${( baseCurrencyInvestmentRatio * 100 ).toPrecision(3)}% in ${ruleSettings.baseCurrency})`, value: true }; } public getSettings(aUserSettings: UserSettings): Settings { return { baseCurrency: aUserSettings.baseCurrency, isActive: true }; } } interface Settings extends RuleSettings { baseCurrency: Currency; }