From 2b97bbd05daabad45afe0fd11ca05a4298b323e0 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 9 Apr 2024 13:44:23 +0200 Subject: [PATCH] Move getChart() to portfolio calculator (#3255) --- .../calculator/portfolio-calculator.ts | 34 +++++++++- .../portfolio-position-detail.interface.ts | 6 -- .../src/app/portfolio/portfolio.service.ts | 68 ++----------------- 3 files changed, 37 insertions(+), 71 deletions(-) diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index 488f9ce99..a9dbff442 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -4,9 +4,13 @@ import { CurrentPositions } from '@ghostfolio/api/app/portfolio/interfaces/curre import { PortfolioOrder } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order.interface'; import { TransactionPointSymbol } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point-symbol.interface'; import { TransactionPoint } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point.interface'; -import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; +import { + getFactor, + getInterval +} from '@ghostfolio/api/helper/portfolio.helper'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; +import { MAX_CHART_ITEMS } from '@ghostfolio/common/config'; import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper'; import { DataProviderInfo, @@ -17,10 +21,11 @@ import { TimelinePosition, UniqueAsset } from '@ghostfolio/common/interfaces'; -import { GroupBy } from '@ghostfolio/common/types'; +import { DateRange, GroupBy } from '@ghostfolio/common/types'; import { Big } from 'big.js'; import { + differenceInDays, eachDayOfInterval, endOfDay, format, @@ -81,6 +86,31 @@ export abstract class PortfolioCalculator { positions: TimelinePosition[] ): CurrentPositions; + public async getChart({ + dateRange = 'max', + withDataDecimation = true + }: { + dateRange?: DateRange; + withDataDecimation?: boolean; + }): Promise { + if (this.getTransactionPoints().length === 0) { + return []; + } + + const { endDate, startDate } = getInterval(dateRange, this.getStartDate()); + + const daysInMarket = differenceInDays(endDate, startDate) + 1; + const step = withDataDecimation + ? Math.round(daysInMarket / Math.min(daysInMarket, MAX_CHART_ITEMS)) + : 1; + + return this.getChartData({ + step, + end: endDate, + start: startDate + }); + } + public async getChartData({ end = new Date(Date.now()), start, diff --git a/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts b/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts index c058a0249..a32d47e21 100644 --- a/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts @@ -36,9 +36,3 @@ export interface PortfolioPositionDetail { transactionCount: number; value: number; } - -export interface HistoricalDataContainer { - isAllTimeHigh: boolean; - isAllTimeLow: boolean; - items: HistoricalDataItem[]; -} diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 99fb47e2c..198395e51 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -21,7 +21,6 @@ import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/sy import { DEFAULT_CURRENCY, EMERGENCY_FUND_TAG_ID, - MAX_CHART_ITEMS, UNKNOWN_KEY } from '@ghostfolio/common/config'; import { @@ -63,8 +62,7 @@ import { DataSource, Order, Platform, - Prisma, - SymbolProfile + Prisma } from '@prisma/client'; import { Big } from 'big.js'; import { isUUID } from 'class-validator'; @@ -80,15 +78,11 @@ import { } from 'date-fns'; import { isEmpty, isNumber, last, uniq, uniqBy } from 'lodash'; -import { PortfolioCalculator } from './calculator/portfolio-calculator'; import { PerformanceCalculationType, PortfolioCalculatorFactory } from './calculator/portfolio-calculator.factory'; -import { - HistoricalDataContainer, - PortfolioPositionDetail -} from './interfaces/portfolio-position-detail.interface'; +import { PortfolioPositionDetail } from './interfaces/portfolio-position-detail.interface'; import { RulesService } from './rules.service'; const asiaPacificMarkets = require('../../assets/countries/asia-pacific-markets.json'); @@ -292,11 +286,8 @@ export class PortfolioService { currency: this.request.user.Settings.settings.baseCurrency }); - const { items } = await this.getChart({ + const items = await portfolioCalculator.getChart({ dateRange, - impersonationId, - portfolioCalculator, - userId, withDataDecimation: false }); @@ -1161,11 +1152,8 @@ export class PortfolioService { let currentNetPerformanceWithCurrencyEffect = netPerformanceWithCurrencyEffect; - const { items } = await this.getChart({ - dateRange, - impersonationId, - portfolioCalculator, - userId + const items = await portfolioCalculator.getChart({ + dateRange }); const itemOfToday = items.find(({ date }) => { @@ -1381,52 +1369,6 @@ export class PortfolioService { return cashPositions; } - private async getChart({ - dateRange = 'max', - impersonationId, - portfolioCalculator, - userId, - withDataDecimation = true - }: { - dateRange?: DateRange; - impersonationId: string; - portfolioCalculator: PortfolioCalculator; - userId: string; - withDataDecimation?: boolean; - }): Promise { - if (portfolioCalculator.getTransactionPoints().length === 0) { - return { - isAllTimeHigh: false, - isAllTimeLow: false, - items: [] - }; - } - - userId = await this.getUserId(impersonationId, userId); - - const { endDate, startDate } = getInterval( - dateRange, - portfolioCalculator.getStartDate() - ); - - const daysInMarket = differenceInDays(endDate, startDate) + 1; - const step = withDataDecimation - ? Math.round(daysInMarket / Math.min(daysInMarket, MAX_CHART_ITEMS)) - : 1; - - const items = await portfolioCalculator.getChartData({ - step, - end: endDate, - start: startDate - }); - - return { - items, - isAllTimeHigh: false, - isAllTimeLow: false - }; - } - private getDividendsByGroup({ dividends, groupBy