Browse Source

Feature/Set up account cluster risks localization (Current Investment) (#5012)

* Set up localization

* Update changelog
pull/5022/head
Tobias Kugel 1 week ago
committed by GitHub
parent
commit
84c4d79a74
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 2
      apps/api/src/app/portfolio/portfolio.service.ts
  3. 9
      apps/api/src/app/user/user.service.ts
  4. 63
      apps/api/src/models/rules/account-cluster-risk/current-investment.ts
  5. 10
      apps/client/src/app/pages/i18n/i18n-page.html

1
CHANGELOG.md

@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- Set up the language localization for the static portfolio analysis rule: _Account Cluster Risks_ (Current Investment)
- Extended the data providers management of the admin control panel by the online status - Extended the data providers management of the admin control panel by the online status
### Changed ### Changed

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

@ -1260,6 +1260,8 @@ export class PortfolioService {
[ [
new AccountClusterRiskCurrentInvestment( new AccountClusterRiskCurrentInvestment(
this.exchangeRateDataService, this.exchangeRateDataService,
this.i18nService,
userSettings.language,
accounts accounts
), ),
new AccountClusterRiskSingleAccount( new AccountClusterRiskSingleAccount(

9
apps/api/src/app/user/user.service.ts

@ -259,9 +259,12 @@ export class UserService {
(user.Settings.settings as UserSettings).xRayRules = { (user.Settings.settings as UserSettings).xRayRules = {
AccountClusterRiskCurrentInvestment: AccountClusterRiskCurrentInvestment:
new AccountClusterRiskCurrentInvestment(undefined, {}).getSettings( new AccountClusterRiskCurrentInvestment(
user.Settings.settings undefined,
), undefined,
undefined,
{}
).getSettings(user.Settings.settings),
AccountClusterRiskSingleAccount: new AccountClusterRiskSingleAccount( AccountClusterRiskSingleAccount: new AccountClusterRiskSingleAccount(
undefined, undefined,
undefined, undefined,

63
apps/api/src/models/rules/account-cluster-risk/current-investment.ts

@ -1,20 +1,22 @@
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface'; import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
import { Rule } from '@ghostfolio/api/models/rule'; import { Rule } from '@ghostfolio/api/models/rule';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service';
PortfolioDetails, import { PortfolioDetails, UserSettings } from '@ghostfolio/common/interfaces';
PortfolioPosition,
UserSettings import { Account } from '@prisma/client';
} from '@ghostfolio/common/interfaces';
export class AccountClusterRiskCurrentInvestment extends Rule<Settings> { export class AccountClusterRiskCurrentInvestment extends Rule<Settings> {
private accounts: PortfolioDetails['accounts']; private accounts: PortfolioDetails['accounts'];
public constructor( public constructor(
protected exchangeRateDataService: ExchangeRateDataService, protected exchangeRateDataService: ExchangeRateDataService,
private i18nService: I18nService,
languageCode: string,
accounts: PortfolioDetails['accounts'] accounts: PortfolioDetails['accounts']
) { ) {
super(exchangeRateDataService, { super(exchangeRateDataService, {
languageCode,
key: AccountClusterRiskCurrentInvestment.name key: AccountClusterRiskCurrentInvestment.name
}); });
@ -23,54 +25,62 @@ export class AccountClusterRiskCurrentInvestment extends Rule<Settings> {
public evaluate(ruleSettings: Settings) { public evaluate(ruleSettings: Settings) {
const accounts: { const accounts: {
[symbol: string]: Pick<PortfolioPosition, 'name'> & { [symbol: string]: Pick<Account, 'name'> & {
investment: number; investment: number;
}; };
} = {}; } = {};
for (const [accountId, account] of Object.entries(this.accounts)) { for (const [accountId, account] of Object.entries(this.accounts)) {
accounts[accountId] = { accounts[accountId] = {
name: account.name, investment: account.valueInBaseCurrency,
investment: account.valueInBaseCurrency name: account.name
}; };
} }
let maxItem: (typeof accounts)[0]; let maxAccount: (typeof accounts)[0];
let totalInvestment = 0; let totalInvestment = 0;
for (const account of Object.values(accounts)) { for (const account of Object.values(accounts)) {
if (!maxItem) { if (!maxAccount) {
maxItem = account; maxAccount = account;
} }
// Calculate total investment // Calculate total investment
totalInvestment += account.investment; totalInvestment += account.investment;
// Find maximum // Find maximum
if (account.investment > maxItem?.investment) { if (account.investment > maxAccount?.investment) {
maxItem = account; maxAccount = account;
} }
} }
const maxInvestmentRatio = maxItem?.investment / totalInvestment || 0; const maxInvestmentRatio = maxAccount?.investment / totalInvestment || 0;
if (maxInvestmentRatio > ruleSettings.thresholdMax) { if (maxInvestmentRatio > ruleSettings.thresholdMax) {
return { return {
evaluation: `Over ${ evaluation: this.i18nService.getTranslation({
ruleSettings.thresholdMax * 100 id: 'rule.accountClusterRiskCurrentInvestment.false',
}% of your current investment is at ${maxItem.name} (${( languageCode: this.getLanguageCode(),
maxInvestmentRatio * 100 placeholders: {
).toPrecision(3)}%)`, maxAccountName: maxAccount.name,
maxInvestmentRatio: (maxInvestmentRatio * 100).toPrecision(3),
thresholdMax: ruleSettings.thresholdMax * 100
}
}),
value: false value: false
}; };
} }
return { return {
evaluation: `The major part of your current investment is at ${ evaluation: this.i18nService.getTranslation({
maxItem.name id: 'rule.accountClusterRiskCurrentInvestment.true',
} (${(maxInvestmentRatio * 100).toPrecision(3)}%) and does not exceed ${ languageCode: this.getLanguageCode(),
ruleSettings.thresholdMax * 100 placeholders: {
}%`, maxAccountName: maxAccount.name,
maxInvestmentRatio: (maxInvestmentRatio * 100).toPrecision(3),
thresholdMax: ruleSettings.thresholdMax * 100
}
}),
value: true value: true
}; };
} }
@ -88,7 +98,10 @@ export class AccountClusterRiskCurrentInvestment extends Rule<Settings> {
} }
public getName() { public getName() {
return 'Investment'; return this.i18nService.getTranslation({
id: 'rule.accountClusterRiskCurrentInvestment',
languageCode: this.getLanguageCode()
});
} }
public getSettings({ baseCurrency, xRayRules }: UserSettings): Settings { public getSettings({ baseCurrency, xRayRules }: UserSettings): Settings {

10
apps/client/src/app/pages/i18n/i18n-page.html

@ -11,6 +11,16 @@
performance, portfolio, software, stock, trading, wealth, web3 performance, portfolio, software, stock, trading, wealth, web3
</li> </li>
<li i18n="@@myAccount">My Account</li> <li i18n="@@myAccount">My Account</li>
<li i18n="@@rule.accountClusterRiskCurrentInvestment">Investment</li>
<li i18n="@@rule.accountClusterRiskCurrentInvestment.false">
Over $&#123;thresholdMax&#125;% of your current investment is at
$&#123;maxAccountName&#125; ($&#123;maxInvestmentRatio&#125;%)
</li>
<li i18n="@@rule.accountClusterRiskCurrentInvestment.true">
The major part of your current investment is at
$&#123;maxAccountName&#125; ($&#123;maxInvestmentRatio&#125;%) and does
not exceed $&#123;thresholdMax&#125;%
</li>
<li i18n="@@rule.accountClusterRiskSingleAccount">Single Account</li> <li i18n="@@rule.accountClusterRiskSingleAccount">Single Account</li>
<li i18n="@@rule.accountClusterRiskSingleAccount.false"> <li i18n="@@rule.accountClusterRiskSingleAccount.false">
Your net worth is managed by a single account Your net worth is managed by a single account

Loading…
Cancel
Save