diff --git a/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts index 978f1f3aa..a90f32c98 100644 --- a/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts @@ -1,10 +1,7 @@ import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; import { PortfolioSnapshot } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-snapshot.interface'; -import { - SymbolMetrics, - TimelinePosition, - UniqueAsset -} from '@ghostfolio/common/interfaces'; +import { SymbolMetrics, UniqueAsset } from '@ghostfolio/common/interfaces'; +import { TimelinePosition } from '@ghostfolio/common/models'; export class MWRPortfolioCalculator extends PortfolioCalculator { protected calculateOverallPerformance( diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index 9458fb1bd..62d36aebb 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -3,11 +3,8 @@ import { PortfolioOrderItem } from '@ghostfolio/api/app/portfolio/interfaces/por import { PortfolioSnapshot } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-snapshot.interface'; import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; import { DATE_FORMAT } from '@ghostfolio/common/helper'; -import { - SymbolMetrics, - TimelinePosition, - UniqueAsset -} from '@ghostfolio/common/interfaces'; +import { SymbolMetrics, UniqueAsset } from '@ghostfolio/common/interfaces'; +import { TimelinePosition } from '@ghostfolio/common/models'; import { Logger } from '@nestjs/common'; import { Big } from 'big.js'; diff --git a/apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts b/apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts index d89734987..f8bba2113 100644 --- a/apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts @@ -1,4 +1,5 @@ -import { ResponseError, TimelinePosition } from '@ghostfolio/common/interfaces'; +import { ResponseError } from '@ghostfolio/common/interfaces'; +import { TimelinePosition } from '@ghostfolio/common/models'; import { Big } from 'big.js'; diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 4e56f844b..a724e5d98 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -29,6 +29,7 @@ import { EnhancedSymbolProfile, Filter, HistoricalDataItem, + InvestmentItem, PortfolioDetails, PortfolioInvestments, PortfolioPerformanceResponse, @@ -36,10 +37,9 @@ import { PortfolioReport, PortfolioSummary, Position, - TimelinePosition, UserSettings } from '@ghostfolio/common/interfaces'; -import { InvestmentItem } from '@ghostfolio/common/interfaces/investment-item.interface'; +import { TimelinePosition } from '@ghostfolio/common/models'; import type { AccountWithValue, DateRange, diff --git a/apps/api/src/models/rule.ts b/apps/api/src/models/rule.ts index ba37f4e94..8397f3e46 100644 --- a/apps/api/src/models/rule.ts +++ b/apps/api/src/models/rule.ts @@ -1,7 +1,8 @@ import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { groupBy } from '@ghostfolio/common/helper'; -import { TimelinePosition, UserSettings } from '@ghostfolio/common/interfaces'; +import { UserSettings } from '@ghostfolio/common/interfaces'; +import { TimelinePosition } from '@ghostfolio/common/models'; import { EvaluationResult } from './interfaces/evaluation-result.interface'; import { RuleInterface } from './interfaces/rule.interface'; diff --git a/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts b/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts index 39406e6c2..372250dbc 100644 --- a/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts +++ b/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts @@ -1,7 +1,8 @@ import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface'; import { Rule } from '@ghostfolio/api/models/rule'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; -import { TimelinePosition, UserSettings } from '@ghostfolio/common/interfaces'; +import { UserSettings } from '@ghostfolio/common/interfaces'; +import { TimelinePosition } from '@ghostfolio/common/models'; export class CurrencyClusterRiskBaseCurrencyCurrentInvestment extends Rule { private positions: TimelinePosition[]; diff --git a/apps/api/src/models/rules/currency-cluster-risk/current-investment.ts b/apps/api/src/models/rules/currency-cluster-risk/current-investment.ts index 078aaba9b..8ebb24ac0 100644 --- a/apps/api/src/models/rules/currency-cluster-risk/current-investment.ts +++ b/apps/api/src/models/rules/currency-cluster-risk/current-investment.ts @@ -1,7 +1,8 @@ import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface'; import { Rule } from '@ghostfolio/api/models/rule'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; -import { TimelinePosition, UserSettings } from '@ghostfolio/common/interfaces'; +import { UserSettings } from '@ghostfolio/common/interfaces'; +import { TimelinePosition } from '@ghostfolio/common/models'; export class CurrencyClusterRiskCurrentInvestment extends Rule { private positions: TimelinePosition[]; diff --git a/libs/common/src/lib/class-transformer.ts b/libs/common/src/lib/class-transformer.ts new file mode 100644 index 000000000..bd9db22da --- /dev/null +++ b/libs/common/src/lib/class-transformer.ts @@ -0,0 +1,9 @@ +import { Big } from 'big.js'; + +export function transformToBig({ value }: { value: string }): Big { + if (value === null) { + return null; + } + + return new Big(value); +} diff --git a/libs/common/src/lib/interfaces/index.ts b/libs/common/src/lib/interfaces/index.ts index dba1ac79a..c2c9ce619 100644 --- a/libs/common/src/lib/interfaces/index.ts +++ b/libs/common/src/lib/interfaces/index.ts @@ -48,7 +48,6 @@ import type { Subscription } from './subscription.interface'; import type { SymbolMetrics } from './symbol-metrics.interface'; import type { SystemMessage } from './system-message.interface'; import type { TabConfiguration } from './tab-configuration.interface'; -import type { TimelinePosition } from './timeline-position.interface'; import type { UniqueAsset } from './unique-asset.interface'; import type { UserSettings } from './user-settings.interface'; import type { User } from './user.interface'; @@ -102,7 +101,6 @@ export { Subscription, SymbolMetrics, TabConfiguration, - TimelinePosition, UniqueAsset, User, UserSettings diff --git a/libs/common/src/lib/interfaces/timeline-position.interface.ts b/libs/common/src/lib/interfaces/timeline-position.interface.ts deleted file mode 100644 index 539f887ce..000000000 --- a/libs/common/src/lib/interfaces/timeline-position.interface.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { DataSource, Tag } from '@prisma/client'; -import { Big } from 'big.js'; - -export interface TimelinePosition { - averagePrice: Big; - currency: string; - dataSource: DataSource; - dividend: Big; - dividendInBaseCurrency: Big; - fee: Big; - firstBuyDate: string; - grossPerformance: Big; - grossPerformancePercentage: Big; - grossPerformancePercentageWithCurrencyEffect: Big; - grossPerformanceWithCurrencyEffect: Big; - investment: Big; - investmentWithCurrencyEffect: Big; - marketPrice: number; - marketPriceInBaseCurrency: number; - netPerformance: Big; - netPerformancePercentage: Big; - netPerformancePercentageWithCurrencyEffect: Big; - netPerformanceWithCurrencyEffect: Big; - quantity: Big; - symbol: string; - tags?: Tag[]; - timeWeightedInvestment: Big; - timeWeightedInvestmentWithCurrencyEffect: Big; - transactionCount: number; - valueInBaseCurrency: Big; -} diff --git a/libs/common/src/lib/models/index.ts b/libs/common/src/lib/models/index.ts new file mode 100644 index 000000000..e5f81fe3b --- /dev/null +++ b/libs/common/src/lib/models/index.ts @@ -0,0 +1,3 @@ +import { TimelinePosition } from './timeline-position'; + +export { TimelinePosition }; diff --git a/libs/common/src/lib/models/timeline-position.ts b/libs/common/src/lib/models/timeline-position.ts new file mode 100644 index 000000000..412449590 --- /dev/null +++ b/libs/common/src/lib/models/timeline-position.ts @@ -0,0 +1,92 @@ +import { transformToBig } from '@ghostfolio/common/class-transformer'; + +import { DataSource, Tag } from '@prisma/client'; +import { Big } from 'big.js'; +import { Transform, Type } from 'class-transformer'; + +export class TimelinePosition { + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + averagePrice: Big; + + currency: string; + dataSource: DataSource; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + dividend: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + dividendInBaseCurrency: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + fee: Big; + + firstBuyDate: string; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + grossPerformance: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + grossPerformancePercentage: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + grossPerformancePercentageWithCurrencyEffect: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + grossPerformanceWithCurrencyEffect: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + investment: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + investmentWithCurrencyEffect: Big; + + marketPrice: number; + marketPriceInBaseCurrency: number; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + netPerformance: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + netPerformancePercentage: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + netPerformancePercentageWithCurrencyEffect: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + netPerformanceWithCurrencyEffect: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + quantity: Big; + + symbol: string; + tags?: Tag[]; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + timeWeightedInvestment: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + timeWeightedInvestmentWithCurrencyEffect: Big; + + transactionCount: number; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + valueInBaseCurrency: Big; +}