refactor rule settings
This commit is contained in:
parent
c47578bd3e
commit
9834c52739
@ -0,0 +1,3 @@
|
|||||||
|
export interface RuleSettings {
|
||||||
|
isActive: boolean;
|
||||||
|
}
|
@ -1,15 +1,17 @@
|
|||||||
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
|
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
|
||||||
|
|
||||||
|
import { UserSettings } from '@ghostfolio/api/models/interfaces/user-settings.interface';
|
||||||
import { EvaluationResult } from './evaluation-result.interface';
|
import { EvaluationResult } from './evaluation-result.interface';
|
||||||
|
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
|
||||||
|
|
||||||
export interface RuleInterface {
|
export interface RuleInterface<T extends RuleSettings> {
|
||||||
evaluate(
|
evaluate(
|
||||||
aPortfolioPositionMap: {
|
aPortfolioPositionMap: {
|
||||||
[symbol: string]: PortfolioPosition;
|
[symbol: string]: PortfolioPosition;
|
||||||
},
|
},
|
||||||
aFees: number,
|
aFees: number,
|
||||||
aRuleSettingsMap: {
|
aRuleSettings: T
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
): EvaluationResult;
|
): EvaluationResult;
|
||||||
|
|
||||||
|
getSettings(aUserSettings: UserSettings): T;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
import { Currency } from '@prisma/client';
|
||||||
|
|
||||||
|
export interface UserSettings {
|
||||||
|
baseCurrency: Currency;
|
||||||
|
}
|
@ -445,10 +445,13 @@ export class Portfolio implements PortfolioInterface {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fees = this.getFees();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
rules: {
|
rules: {
|
||||||
accountClusterRisk: await this.rulesService.evaluate(
|
accountClusterRisk: await this.rulesService.evaluate(
|
||||||
this,
|
details,
|
||||||
|
fees,
|
||||||
[
|
[
|
||||||
new AccountClusterRiskInitialInvestment(
|
new AccountClusterRiskInitialInvestment(
|
||||||
this.exchangeRateDataService
|
this.exchangeRateDataService
|
||||||
@ -461,7 +464,8 @@ export class Portfolio implements PortfolioInterface {
|
|||||||
{ baseCurrency: this.user.Settings.currency }
|
{ baseCurrency: this.user.Settings.currency }
|
||||||
),
|
),
|
||||||
currencyClusterRisk: await this.rulesService.evaluate(
|
currencyClusterRisk: await this.rulesService.evaluate(
|
||||||
this,
|
details,
|
||||||
|
fees,
|
||||||
[
|
[
|
||||||
new CurrencyClusterRiskBaseCurrencyInitialInvestment(
|
new CurrencyClusterRiskBaseCurrencyInitialInvestment(
|
||||||
this.exchangeRateDataService
|
this.exchangeRateDataService
|
||||||
@ -479,7 +483,8 @@ export class Portfolio implements PortfolioInterface {
|
|||||||
{ baseCurrency: this.user.Settings.currency }
|
{ baseCurrency: this.user.Settings.currency }
|
||||||
),
|
),
|
||||||
fees: await this.rulesService.evaluate(
|
fees: await this.rulesService.evaluate(
|
||||||
this,
|
details,
|
||||||
|
fees,
|
||||||
[new FeeRatioInitialInvestment(this.exchangeRateDataService)],
|
[new FeeRatioInitialInvestment(this.exchangeRateDataService)],
|
||||||
{ baseCurrency: this.user.Settings.currency }
|
{ baseCurrency: this.user.Settings.currency }
|
||||||
)
|
)
|
||||||
|
@ -5,8 +5,10 @@ import { Currency } from '@prisma/client';
|
|||||||
import { ExchangeRateDataService } from '../services/exchange-rate-data.service';
|
import { ExchangeRateDataService } from '../services/exchange-rate-data.service';
|
||||||
import { EvaluationResult } from './interfaces/evaluation-result.interface';
|
import { EvaluationResult } from './interfaces/evaluation-result.interface';
|
||||||
import { RuleInterface } from './interfaces/rule.interface';
|
import { RuleInterface } from './interfaces/rule.interface';
|
||||||
|
import { UserSettings } from '@ghostfolio/api/models/interfaces/user-settings.interface';
|
||||||
|
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
|
||||||
|
|
||||||
export abstract class Rule implements RuleInterface {
|
export abstract class Rule<T extends RuleSettings> implements RuleInterface<T> {
|
||||||
private name: string;
|
private name: string;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
@ -25,11 +27,11 @@ export abstract class Rule implements RuleInterface {
|
|||||||
[symbol: string]: PortfolioPosition;
|
[symbol: string]: PortfolioPosition;
|
||||||
},
|
},
|
||||||
aFees: number,
|
aFees: number,
|
||||||
aRuleSettingsMap?: {
|
aRuleSettings: T
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
): EvaluationResult;
|
): EvaluationResult;
|
||||||
|
|
||||||
|
public abstract getSettings(aUserSettings: UserSettings): T;
|
||||||
|
|
||||||
public getName() {
|
public getName() {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,10 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-
|
|||||||
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
|
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
|
||||||
|
|
||||||
import { Rule } from '../../rule';
|
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 AccountClusterRiskCurrentInvestment extends Rule {
|
export class AccountClusterRiskCurrentInvestment extends Rule<Settings> {
|
||||||
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
|
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
|
||||||
super(exchangeRateDataService, {
|
super(exchangeRateDataService, {
|
||||||
name: 'Current Investment'
|
name: 'Current Investment'
|
||||||
@ -13,13 +15,8 @@ export class AccountClusterRiskCurrentInvestment extends Rule {
|
|||||||
public evaluate(
|
public evaluate(
|
||||||
aPositions: { [symbol: string]: PortfolioPosition },
|
aPositions: { [symbol: string]: PortfolioPosition },
|
||||||
aFees: number,
|
aFees: number,
|
||||||
aRuleSettingsMap?: {
|
ruleSettings?: Settings
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
) {
|
) {
|
||||||
const ruleSettings =
|
|
||||||
aRuleSettingsMap[AccountClusterRiskCurrentInvestment.name];
|
|
||||||
|
|
||||||
const accounts: {
|
const accounts: {
|
||||||
[symbol: string]: Pick<PortfolioPosition, 'name'> & {
|
[symbol: string]: Pick<PortfolioPosition, 'name'> & {
|
||||||
investment: number;
|
investment: number;
|
||||||
@ -78,4 +75,17 @@ export class AccountClusterRiskCurrentInvestment extends Rule {
|
|||||||
value: true
|
value: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getSettings(aUserSettings: UserSettings): Settings {
|
||||||
|
return {
|
||||||
|
baseCurrency: aUserSettings.baseCurrency,
|
||||||
|
isActive: true,
|
||||||
|
threshold: 0.5
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Settings extends RuleSettings {
|
||||||
|
baseCurrency: string;
|
||||||
|
threshold: number;
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,10 @@ import { PortfolioPosition } from '@ghostfolio/common/interfaces';
|
|||||||
import { ExchangeRateDataService } from 'apps/api/src/services/exchange-rate-data.service';
|
import { ExchangeRateDataService } from 'apps/api/src/services/exchange-rate-data.service';
|
||||||
|
|
||||||
import { Rule } from '../../rule';
|
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 AccountClusterRiskInitialInvestment extends Rule {
|
export class AccountClusterRiskInitialInvestment extends Rule<Settings> {
|
||||||
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
|
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
|
||||||
super(exchangeRateDataService, {
|
super(exchangeRateDataService, {
|
||||||
name: 'Initial Investment'
|
name: 'Initial Investment'
|
||||||
@ -13,13 +15,8 @@ export class AccountClusterRiskInitialInvestment extends Rule {
|
|||||||
public evaluate(
|
public evaluate(
|
||||||
aPositions: { [symbol: string]: PortfolioPosition },
|
aPositions: { [symbol: string]: PortfolioPosition },
|
||||||
aFees: number,
|
aFees: number,
|
||||||
aRuleSettingsMap?: {
|
ruleSettings?: Settings
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
) {
|
) {
|
||||||
const ruleSettings =
|
|
||||||
aRuleSettingsMap[AccountClusterRiskInitialInvestment.name];
|
|
||||||
|
|
||||||
const platforms: {
|
const platforms: {
|
||||||
[symbol: string]: Pick<PortfolioPosition, 'name'> & {
|
[symbol: string]: Pick<PortfolioPosition, 'name'> & {
|
||||||
investment: number;
|
investment: number;
|
||||||
@ -78,4 +75,18 @@ export class AccountClusterRiskInitialInvestment extends Rule {
|
|||||||
value: true
|
value: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getSettings(aUserSettings: UserSettings): Settings {
|
||||||
|
return {
|
||||||
|
baseCurrency: aUserSettings.baseCurrency,
|
||||||
|
isActive: true,
|
||||||
|
threshold: 0.5
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Settings extends RuleSettings {
|
||||||
|
baseCurrency: string;
|
||||||
|
isActive: boolean;
|
||||||
|
threshold: number;
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,10 @@ import { PortfolioPosition } from '@ghostfolio/common/interfaces';
|
|||||||
import { ExchangeRateDataService } from 'apps/api/src/services/exchange-rate-data.service';
|
import { ExchangeRateDataService } from 'apps/api/src/services/exchange-rate-data.service';
|
||||||
|
|
||||||
import { Rule } from '../../rule';
|
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 AccountClusterRiskSingleAccount extends Rule {
|
export class AccountClusterRiskSingleAccount extends Rule<RuleSettings> {
|
||||||
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
|
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
|
||||||
super(exchangeRateDataService, {
|
super(exchangeRateDataService, {
|
||||||
name: 'Single Account'
|
name: 'Single Account'
|
||||||
@ -33,4 +35,10 @@ export class AccountClusterRiskSingleAccount extends Rule {
|
|||||||
value: true
|
value: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getSettings(aUserSettings: UserSettings): RuleSettings {
|
||||||
|
return {
|
||||||
|
isActive: true
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
|
import { Currency } from '@prisma/client';
|
||||||
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data.service';
|
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data.service';
|
||||||
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
|
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
|
||||||
|
|
||||||
import { Rule } from '../../rule';
|
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 CurrencyClusterRiskBaseCurrencyCurrentInvestment extends Rule {
|
export class CurrencyClusterRiskBaseCurrencyCurrentInvestment extends Rule<Settings> {
|
||||||
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
|
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
|
||||||
super(exchangeRateDataService, {
|
super(exchangeRateDataService, {
|
||||||
name: 'Current Investment: Base Currency'
|
name: 'Current Investment: Base Currency'
|
||||||
@ -13,13 +16,8 @@ export class CurrencyClusterRiskBaseCurrencyCurrentInvestment extends Rule {
|
|||||||
public evaluate(
|
public evaluate(
|
||||||
aPositions: { [symbol: string]: PortfolioPosition },
|
aPositions: { [symbol: string]: PortfolioPosition },
|
||||||
aFees: number,
|
aFees: number,
|
||||||
aRuleSettingsMap?: {
|
ruleSettings: Settings
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
) {
|
) {
|
||||||
const ruleSettings =
|
|
||||||
aRuleSettingsMap[CurrencyClusterRiskBaseCurrencyCurrentInvestment.name];
|
|
||||||
|
|
||||||
const positionsGroupedByCurrency = this.groupPositionsByAttribute(
|
const positionsGroupedByCurrency = this.groupPositionsByAttribute(
|
||||||
aPositions,
|
aPositions,
|
||||||
'currency',
|
'currency',
|
||||||
@ -61,4 +59,15 @@ export class CurrencyClusterRiskBaseCurrencyCurrentInvestment extends Rule {
|
|||||||
value: true
|
value: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getSettings(aUserSettings: UserSettings): Settings {
|
||||||
|
return {
|
||||||
|
baseCurrency: aUserSettings.baseCurrency,
|
||||||
|
isActive: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Settings extends RuleSettings {
|
||||||
|
baseCurrency: Currency;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
|
import { Currency } from '@prisma/client';
|
||||||
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
|
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
|
||||||
import { ExchangeRateDataService } from 'apps/api/src/services/exchange-rate-data.service';
|
import { ExchangeRateDataService } from 'apps/api/src/services/exchange-rate-data.service';
|
||||||
|
|
||||||
import { Rule } from '../../rule';
|
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 {
|
export class CurrencyClusterRiskBaseCurrencyInitialInvestment extends Rule<Settings> {
|
||||||
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
|
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
|
||||||
super(exchangeRateDataService, {
|
super(exchangeRateDataService, {
|
||||||
name: 'Initial Investment: Base Currency'
|
name: 'Initial Investment: Base Currency'
|
||||||
@ -13,13 +16,8 @@ export class CurrencyClusterRiskBaseCurrencyInitialInvestment extends Rule {
|
|||||||
public evaluate(
|
public evaluate(
|
||||||
aPositions: { [symbol: string]: PortfolioPosition },
|
aPositions: { [symbol: string]: PortfolioPosition },
|
||||||
aFees: number,
|
aFees: number,
|
||||||
aRuleSettingsMap?: {
|
ruleSettings: Settings
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
) {
|
) {
|
||||||
const ruleSettings =
|
|
||||||
aRuleSettingsMap[CurrencyClusterRiskBaseCurrencyInitialInvestment.name];
|
|
||||||
|
|
||||||
const positionsGroupedByCurrency = this.groupPositionsByAttribute(
|
const positionsGroupedByCurrency = this.groupPositionsByAttribute(
|
||||||
aPositions,
|
aPositions,
|
||||||
'currency',
|
'currency',
|
||||||
@ -62,4 +60,15 @@ export class CurrencyClusterRiskBaseCurrencyInitialInvestment extends Rule {
|
|||||||
value: true
|
value: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getSettings(aUserSettings: UserSettings): Settings {
|
||||||
|
return {
|
||||||
|
baseCurrency: aUserSettings.baseCurrency,
|
||||||
|
isActive: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Settings extends RuleSettings {
|
||||||
|
baseCurrency: Currency;
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,11 @@ import { PortfolioPosition } from '@ghostfolio/common/interfaces';
|
|||||||
import { ExchangeRateDataService } from 'apps/api/src/services/exchange-rate-data.service';
|
import { ExchangeRateDataService } from 'apps/api/src/services/exchange-rate-data.service';
|
||||||
|
|
||||||
import { Rule } from '../../rule';
|
import { Rule } from '../../rule';
|
||||||
|
import { UserSettings } from '@ghostfolio/api/models/interfaces/user-settings.interface';
|
||||||
|
import { Currency } from '@prisma/client';
|
||||||
|
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
|
||||||
|
|
||||||
export class CurrencyClusterRiskCurrentInvestment extends Rule {
|
export class CurrencyClusterRiskCurrentInvestment extends Rule<Settings> {
|
||||||
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
|
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
|
||||||
super(exchangeRateDataService, {
|
super(exchangeRateDataService, {
|
||||||
name: 'Current Investment'
|
name: 'Current Investment'
|
||||||
@ -13,13 +16,8 @@ export class CurrencyClusterRiskCurrentInvestment extends Rule {
|
|||||||
public evaluate(
|
public evaluate(
|
||||||
aPositions: { [symbol: string]: PortfolioPosition },
|
aPositions: { [symbol: string]: PortfolioPosition },
|
||||||
aFees: number,
|
aFees: number,
|
||||||
aRuleSettingsMap?: {
|
ruleSettings: Settings
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
) {
|
) {
|
||||||
const ruleSettings =
|
|
||||||
aRuleSettingsMap[CurrencyClusterRiskCurrentInvestment.name];
|
|
||||||
|
|
||||||
const positionsGroupedByCurrency = this.groupPositionsByAttribute(
|
const positionsGroupedByCurrency = this.groupPositionsByAttribute(
|
||||||
aPositions,
|
aPositions,
|
||||||
'currency',
|
'currency',
|
||||||
@ -61,4 +59,17 @@ export class CurrencyClusterRiskCurrentInvestment extends Rule {
|
|||||||
value: true
|
value: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getSettings(aUserSettings: UserSettings): Settings {
|
||||||
|
return {
|
||||||
|
baseCurrency: aUserSettings.baseCurrency,
|
||||||
|
isActive: true,
|
||||||
|
threshold: 0.5
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Settings extends RuleSettings {
|
||||||
|
baseCurrency: Currency;
|
||||||
|
threshold: number;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
|
import { Currency } from '@prisma/client';
|
||||||
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
|
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
|
||||||
import { ExchangeRateDataService } from 'apps/api/src/services/exchange-rate-data.service';
|
import { ExchangeRateDataService } from 'apps/api/src/services/exchange-rate-data.service';
|
||||||
|
|
||||||
import { Rule } from '../../rule';
|
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 CurrencyClusterRiskInitialInvestment extends Rule {
|
export class CurrencyClusterRiskInitialInvestment extends Rule<Settings> {
|
||||||
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
|
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
|
||||||
super(exchangeRateDataService, {
|
super(exchangeRateDataService, {
|
||||||
name: 'Initial Investment'
|
name: 'Initial Investment'
|
||||||
@ -13,13 +16,8 @@ export class CurrencyClusterRiskInitialInvestment extends Rule {
|
|||||||
public evaluate(
|
public evaluate(
|
||||||
aPositions: { [symbol: string]: PortfolioPosition },
|
aPositions: { [symbol: string]: PortfolioPosition },
|
||||||
aFees: number,
|
aFees: number,
|
||||||
aRuleSettingsMap?: {
|
ruleSettings: Settings
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
) {
|
) {
|
||||||
const ruleSettings =
|
|
||||||
aRuleSettingsMap[CurrencyClusterRiskInitialInvestment.name];
|
|
||||||
|
|
||||||
const positionsGroupedByCurrency = this.groupPositionsByAttribute(
|
const positionsGroupedByCurrency = this.groupPositionsByAttribute(
|
||||||
aPositions,
|
aPositions,
|
||||||
'currency',
|
'currency',
|
||||||
@ -61,4 +59,17 @@ export class CurrencyClusterRiskInitialInvestment extends Rule {
|
|||||||
value: true
|
value: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getSettings(aUserSettings: UserSettings): Settings {
|
||||||
|
return {
|
||||||
|
baseCurrency: aUserSettings.baseCurrency,
|
||||||
|
isActive: true,
|
||||||
|
threshold: 0.5
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Settings extends RuleSettings {
|
||||||
|
baseCurrency: Currency;
|
||||||
|
threshold: number;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
|
import { Currency } from '@prisma/client';
|
||||||
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
|
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
|
||||||
import { ExchangeRateDataService } from 'apps/api/src/services/exchange-rate-data.service';
|
import { ExchangeRateDataService } from 'apps/api/src/services/exchange-rate-data.service';
|
||||||
|
|
||||||
import { Rule } from '../../rule';
|
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 FeeRatioInitialInvestment extends Rule {
|
export class FeeRatioInitialInvestment extends Rule<Settings> {
|
||||||
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
|
public constructor(public exchangeRateDataService: ExchangeRateDataService) {
|
||||||
super(exchangeRateDataService, {
|
super(exchangeRateDataService, {
|
||||||
name: 'Initial Investment'
|
name: 'Initial Investment'
|
||||||
@ -13,12 +16,8 @@ export class FeeRatioInitialInvestment extends Rule {
|
|||||||
public evaluate(
|
public evaluate(
|
||||||
aPositions: { [symbol: string]: PortfolioPosition },
|
aPositions: { [symbol: string]: PortfolioPosition },
|
||||||
aFees: number,
|
aFees: number,
|
||||||
aRuleSettingsMap?: {
|
ruleSettings: Settings
|
||||||
[key: string]: any;
|
|
||||||
}
|
|
||||||
) {
|
) {
|
||||||
const ruleSettings = aRuleSettingsMap[FeeRatioInitialInvestment.name];
|
|
||||||
|
|
||||||
const positionsGroupedByCurrency = this.groupPositionsByAttribute(
|
const positionsGroupedByCurrency = this.groupPositionsByAttribute(
|
||||||
aPositions,
|
aPositions,
|
||||||
'currency',
|
'currency',
|
||||||
@ -50,4 +49,17 @@ export class FeeRatioInitialInvestment extends Rule {
|
|||||||
value: true
|
value: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getSettings(aUserSettings: UserSettings): Settings {
|
||||||
|
return {
|
||||||
|
baseCurrency: aUserSettings.baseCurrency,
|
||||||
|
isActive: true,
|
||||||
|
threshold: 0.01
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Settings extends RuleSettings {
|
||||||
|
baseCurrency: Currency;
|
||||||
|
threshold: number;
|
||||||
}
|
}
|
||||||
|
@ -1,78 +1,30 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
import { Portfolio } from '../models/portfolio';
|
|
||||||
import { Rule } from '../models/rule';
|
import { Rule } from '../models/rule';
|
||||||
import { AccountClusterRiskCurrentInvestment } from '../models/rules/account-cluster-risk/current-investment';
|
import { PortfolioPosition } from '@ghostfolio/common/interfaces';
|
||||||
import { AccountClusterRiskInitialInvestment } from '../models/rules/account-cluster-risk/initial-investment';
|
import { Currency } from '@prisma/client';
|
||||||
import { AccountClusterRiskSingleAccount } from '../models/rules/account-cluster-risk/single-account';
|
import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface';
|
||||||
import { CurrencyClusterRiskBaseCurrencyCurrentInvestment } from '../models/rules/currency-cluster-risk/base-currency-current-investment';
|
|
||||||
import { CurrencyClusterRiskBaseCurrencyInitialInvestment } from '../models/rules/currency-cluster-risk/base-currency-initial-investment';
|
|
||||||
import { CurrencyClusterRiskCurrentInvestment } from '../models/rules/currency-cluster-risk/current-investment';
|
|
||||||
import { CurrencyClusterRiskInitialInvestment } from '../models/rules/currency-cluster-risk/initial-investment';
|
|
||||||
import { FeeRatioInitialInvestment } from '../models/rules/fees/fee-ratio-initial-investment';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RulesService {
|
export class RulesService {
|
||||||
public constructor() {}
|
public constructor() {}
|
||||||
|
|
||||||
public async evaluate(
|
public async evaluate<T extends RuleSettings>(
|
||||||
aPortfolio: Portfolio,
|
details: { [p: string]: PortfolioPosition },
|
||||||
aRules: Rule[],
|
fees: number,
|
||||||
aUserSettings: { baseCurrency: string }
|
aRules: Rule<T>[],
|
||||||
|
aUserSettings: { baseCurrency: Currency }
|
||||||
) {
|
) {
|
||||||
const defaultSettings = this.getDefaultRuleSettings(aUserSettings);
|
|
||||||
const details = await aPortfolio.getDetails();
|
|
||||||
|
|
||||||
return aRules
|
return aRules
|
||||||
.filter((rule) => {
|
.filter((rule) => {
|
||||||
return defaultSettings[rule.constructor.name]?.isActive;
|
return rule.getSettings(aUserSettings)?.isActive;
|
||||||
})
|
})
|
||||||
.map((rule) => {
|
.map((rule) => {
|
||||||
const evaluationResult = rule.evaluate(
|
const evaluationResult = rule.evaluate(
|
||||||
details,
|
details,
|
||||||
aPortfolio.getFees(),
|
fees,
|
||||||
defaultSettings
|
rule.getSettings(aUserSettings)
|
||||||
);
|
);
|
||||||
return { ...evaluationResult, name: rule.getName() };
|
return { ...evaluationResult, name: rule.getName() };
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private getDefaultRuleSettings(aUserSettings: { baseCurrency: string }) {
|
|
||||||
return {
|
|
||||||
[AccountClusterRiskCurrentInvestment.name]: {
|
|
||||||
baseCurrency: aUserSettings.baseCurrency,
|
|
||||||
isActive: true,
|
|
||||||
threshold: 0.5
|
|
||||||
},
|
|
||||||
[AccountClusterRiskInitialInvestment.name]: {
|
|
||||||
baseCurrency: aUserSettings.baseCurrency,
|
|
||||||
isActive: true,
|
|
||||||
threshold: 0.5
|
|
||||||
},
|
|
||||||
[AccountClusterRiskSingleAccount.name]: { isActive: true },
|
|
||||||
[CurrencyClusterRiskBaseCurrencyInitialInvestment.name]: {
|
|
||||||
baseCurrency: aUserSettings.baseCurrency,
|
|
||||||
isActive: true
|
|
||||||
},
|
|
||||||
[CurrencyClusterRiskBaseCurrencyCurrentInvestment.name]: {
|
|
||||||
baseCurrency: aUserSettings.baseCurrency,
|
|
||||||
isActive: true
|
|
||||||
},
|
|
||||||
[CurrencyClusterRiskCurrentInvestment.name]: {
|
|
||||||
baseCurrency: aUserSettings.baseCurrency,
|
|
||||||
isActive: true,
|
|
||||||
threshold: 0.5
|
|
||||||
},
|
|
||||||
[CurrencyClusterRiskInitialInvestment.name]: {
|
|
||||||
baseCurrency: aUserSettings.baseCurrency,
|
|
||||||
isActive: true,
|
|
||||||
threshold: 0.5
|
|
||||||
},
|
|
||||||
[FeeRatioInitialInvestment.name]: {
|
|
||||||
baseCurrency: aUserSettings.baseCurrency,
|
|
||||||
isActive: true,
|
|
||||||
threshold: 0.01
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user