change rule service interface

pull/239/head
Valentin Zickner 3 years ago committed by Thomas
parent 9834c52739
commit 72dbe00091

@ -1,17 +1,9 @@
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
import { UserSettings } from '@ghostfolio/api/models/interfaces/user-settings.interface';
import { EvaluationResult } from './evaluation-result.interface';
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
export interface RuleInterface<T extends RuleSettings> {
evaluate(
aPortfolioPositionMap: {
[symbol: string]: PortfolioPosition;
},
aFees: number,
aRuleSettings: T
): EvaluationResult;
evaluate(aRuleSettings: T): EvaluationResult;
getSettings(aUserSettings: UserSettings): T;
}

@ -450,42 +450,51 @@ export class Portfolio implements PortfolioInterface {
return {
rules: {
accountClusterRisk: await this.rulesService.evaluate(
details,
fees,
[
new AccountClusterRiskInitialInvestment(
this.exchangeRateDataService
this.exchangeRateDataService,
details
),
new AccountClusterRiskCurrentInvestment(
this.exchangeRateDataService
this.exchangeRateDataService,
details
),
new AccountClusterRiskSingleAccount(this.exchangeRateDataService)
new AccountClusterRiskSingleAccount(
this.exchangeRateDataService,
details
)
],
{ baseCurrency: this.user.Settings.currency }
),
currencyClusterRisk: await this.rulesService.evaluate(
details,
fees,
[
new CurrencyClusterRiskBaseCurrencyInitialInvestment(
this.exchangeRateDataService
this.exchangeRateDataService,
details
),
new CurrencyClusterRiskBaseCurrencyCurrentInvestment(
this.exchangeRateDataService
this.exchangeRateDataService,
details
),
new CurrencyClusterRiskInitialInvestment(
this.exchangeRateDataService
this.exchangeRateDataService,
details
),
new CurrencyClusterRiskCurrentInvestment(
this.exchangeRateDataService
this.exchangeRateDataService,
details
)
],
{ baseCurrency: this.user.Settings.currency }
),
fees: await this.rulesService.evaluate(
details,
fees,
[new FeeRatioInitialInvestment(this.exchangeRateDataService)],
[
new FeeRatioInitialInvestment(
this.exchangeRateDataService,
details,
fees
)
],
{ baseCurrency: this.user.Settings.currency }
)
}

@ -12,7 +12,7 @@ export abstract class Rule<T extends RuleSettings> implements RuleInterface<T> {
private name: string;
public constructor(
public exchangeRateDataService: ExchangeRateDataService,
protected exchangeRateDataService: ExchangeRateDataService,
{
name
}: {
@ -22,13 +22,7 @@ export abstract class Rule<T extends RuleSettings> implements RuleInterface<T> {
this.name = name;
}
public abstract evaluate(
aPortfolioPositionMap: {
[symbol: string]: PortfolioPosition;
},
aFees: number,
aRuleSettings: T
): EvaluationResult;
public abstract evaluate(aRuleSettings: T): EvaluationResult;
public abstract getSettings(aUserSettings: UserSettings): T;

@ -6,24 +6,23 @@ import { UserSettings } from '@ghostfolio/api/models/interfaces/user-settings.in
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
export class AccountClusterRiskCurrentInvestment extends Rule<Settings> {
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
public constructor(
protected exchangeRateDataService: ExchangeRateDataService,
private positions: { [symbol: string]: PortfolioPosition }
) {
super(exchangeRateDataService, {
name: 'Current Investment'
});
}
public evaluate(
aPositions: { [symbol: string]: PortfolioPosition },
aFees: number,
ruleSettings?: Settings
) {
public evaluate(ruleSettings: Settings) {
const accounts: {
[symbol: string]: Pick<PortfolioPosition, 'name'> & {
investment: number;
};
} = {};
Object.values(aPositions).forEach((position) => {
Object.values(this.positions).forEach((position) => {
for (const [account, { current }] of Object.entries(position.accounts)) {
if (accounts[account]?.investment) {
accounts[account].investment += current;

@ -6,24 +6,23 @@ import { UserSettings } from '@ghostfolio/api/models/interfaces/user-settings.in
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
export class AccountClusterRiskInitialInvestment extends Rule<Settings> {
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
public constructor(
protected exchangeRateDataService: ExchangeRateDataService,
private positions: { [symbol: string]: PortfolioPosition }
) {
super(exchangeRateDataService, {
name: 'Initial Investment'
});
}
public evaluate(
aPositions: { [symbol: string]: PortfolioPosition },
aFees: number,
ruleSettings?: Settings
) {
public evaluate(ruleSettings?: Settings) {
const platforms: {
[symbol: string]: Pick<PortfolioPosition, 'name'> & {
investment: number;
};
} = {};
Object.values(aPositions).forEach((position) => {
Object.values(this.positions).forEach((position) => {
for (const [account, { original }] of Object.entries(position.accounts)) {
if (platforms[account]?.investment) {
platforms[account].investment += original;

@ -6,16 +6,19 @@ import { UserSettings } from '@ghostfolio/api/models/interfaces/user-settings.in
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
export class AccountClusterRiskSingleAccount extends Rule<RuleSettings> {
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
public constructor(
protected exchangeRateDataService: ExchangeRateDataService,
private positions: { [symbol: string]: PortfolioPosition }
) {
super(exchangeRateDataService, {
name: 'Single Account'
});
}
public evaluate(positions: { [symbol: string]: PortfolioPosition }) {
public evaluate() {
const accounts: string[] = [];
Object.values(positions).forEach((position) => {
Object.values(this.positions).forEach((position) => {
for (const [account] of Object.entries(position.accounts)) {
if (!accounts.includes(account)) {
accounts.push(account);

@ -7,19 +7,18 @@ import { UserSettings } from '@ghostfolio/api/models/interfaces/user-settings.in
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
export class CurrencyClusterRiskBaseCurrencyCurrentInvestment extends Rule<Settings> {
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
public constructor(
protected exchangeRateDataService: ExchangeRateDataService,
private positions: { [symbol: string]: PortfolioPosition }
) {
super(exchangeRateDataService, {
name: 'Current Investment: Base Currency'
});
}
public evaluate(
aPositions: { [symbol: string]: PortfolioPosition },
aFees: number,
ruleSettings: Settings
) {
public evaluate(ruleSettings: Settings) {
const positionsGroupedByCurrency = this.groupPositionsByAttribute(
aPositions,
this.positions,
'currency',
ruleSettings.baseCurrency
);

@ -7,19 +7,18 @@ import { UserSettings } from '@ghostfolio/api/models/interfaces/user-settings.in
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
export class CurrencyClusterRiskBaseCurrencyInitialInvestment extends Rule<Settings> {
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
public constructor(
protected exchangeRateDataService: ExchangeRateDataService,
private positions: { [symbol: string]: PortfolioPosition }
) {
super(exchangeRateDataService, {
name: 'Initial Investment: Base Currency'
});
}
public evaluate(
aPositions: { [symbol: string]: PortfolioPosition },
aFees: number,
ruleSettings: Settings
) {
public evaluate(ruleSettings: Settings) {
const positionsGroupedByCurrency = this.groupPositionsByAttribute(
aPositions,
this.positions,
'currency',
ruleSettings.baseCurrency
);

@ -7,19 +7,18 @@ import { Currency } from '@prisma/client';
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
export class CurrencyClusterRiskCurrentInvestment extends Rule<Settings> {
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
public constructor(
public exchangeRateDataService: ExchangeRateDataService,
private positions: { [symbol: string]: PortfolioPosition }
) {
super(exchangeRateDataService, {
name: 'Current Investment'
});
}
public evaluate(
aPositions: { [symbol: string]: PortfolioPosition },
aFees: number,
ruleSettings: Settings
) {
public evaluate(ruleSettings: Settings) {
const positionsGroupedByCurrency = this.groupPositionsByAttribute(
aPositions,
this.positions,
'currency',
ruleSettings.baseCurrency
);

@ -7,19 +7,18 @@ import { UserSettings } from '@ghostfolio/api/models/interfaces/user-settings.in
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
export class CurrencyClusterRiskInitialInvestment extends Rule<Settings> {
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
public constructor(
protected exchangeRateDataService: ExchangeRateDataService,
private positions: { [symbol: string]: PortfolioPosition }
) {
super(exchangeRateDataService, {
name: 'Initial Investment'
});
}
public evaluate(
aPositions: { [symbol: string]: PortfolioPosition },
aFees: number,
ruleSettings: Settings
) {
public evaluate(ruleSettings: Settings) {
const positionsGroupedByCurrency = this.groupPositionsByAttribute(
aPositions,
this.positions,
'currency',
ruleSettings.baseCurrency
);

@ -7,19 +7,19 @@ import { UserSettings } from '@ghostfolio/api/models/interfaces/user-settings.in
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
export class FeeRatioInitialInvestment extends Rule<Settings> {
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
public constructor(
protected exchangeRateDataService: ExchangeRateDataService,
private positions: { [symbol: string]: PortfolioPosition },
private fees: number
) {
super(exchangeRateDataService, {
name: 'Initial Investment'
});
}
public evaluate(
aPositions: { [symbol: string]: PortfolioPosition },
aFees: number,
ruleSettings: Settings
) {
public evaluate(ruleSettings: Settings) {
const positionsGroupedByCurrency = this.groupPositionsByAttribute(
aPositions,
this.positions,
'currency',
ruleSettings.baseCurrency
);
@ -31,7 +31,7 @@ export class FeeRatioInitialInvestment extends Rule<Settings> {
totalInvestment += groupItem.investment;
});
const feeRatio = aFees / totalInvestment;
const feeRatio = this.fees / totalInvestment;
if (feeRatio > ruleSettings.threshold) {
return {

@ -1,6 +1,5 @@
import { Injectable } from '@nestjs/common';
import { Rule } from '../models/rule';
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
import { Currency } from '@prisma/client';
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
@ -9,8 +8,6 @@ export class RulesService {
public constructor() {}
public async evaluate<T extends RuleSettings>(
details: { [p: string]: PortfolioPosition },
fees: number,
aRules: Rule<T>[],
aUserSettings: { baseCurrency: Currency }
) {
@ -19,11 +16,7 @@ export class RulesService {
return rule.getSettings(aUserSettings)?.isActive;
})
.map((rule) => {
const evaluationResult = rule.evaluate(
details,
fees,
rule.getSettings(aUserSettings)
);
const evaluationResult = rule.evaluate(rule.getSettings(aUserSettings));
return { ...evaluationResult, name: rule.getName() };
});
}

Loading…
Cancel
Save