diff --git a/apps/api/src/app/benchmark/benchmark.service.ts b/apps/api/src/app/benchmark/benchmark.service.ts index e223eea50..e7c7ea5ba 100644 --- a/apps/api/src/app/benchmark/benchmark.service.ts +++ b/apps/api/src/app/benchmark/benchmark.service.ts @@ -13,7 +13,8 @@ import { import { DATE_FORMAT, calculateBenchmarkTrend, - parseDate + parseDate, + resetHours } from '@ghostfolio/common/helper'; import { Benchmark, @@ -27,7 +28,13 @@ import { BenchmarkTrend } from '@ghostfolio/common/types'; import { Injectable, Logger } from '@nestjs/common'; import { SymbolProfile } from '@prisma/client'; import { Big } from 'big.js'; -import { format, isSameDay, subDays } from 'date-fns'; +import { + differenceInDays, + eachDayOfInterval, + format, + isSameDay, + subDays +} from 'date-fns'; import { isNumber, last, uniqBy } from 'lodash'; import ms from 'ms'; @@ -209,14 +216,27 @@ export class BenchmarkService { public async getMarketDataBySymbol({ dataSource, startDate, + endDate = new Date(), symbol, userCurrency }: { startDate: Date; + endDate?: Date; userCurrency: string; } & UniqueAsset): Promise { const marketData: { date: string; value: number }[] = []; + const days = differenceInDays(endDate, startDate) + 1; + const step = Math.round(days / Math.min(days, MAX_CHART_ITEMS)); + const dates = eachDayOfInterval( + { start: startDate, end: endDate }, + { step } + ); + + if (!isSameDay(last(dates), endDate)) { + dates.push(resetHours(endDate)); + } + const [currentSymbolItem, marketDataItems] = await Promise.all([ this.symbolService.get({ dataGatheringItem: { @@ -232,7 +252,7 @@ export class BenchmarkService { dataSource, symbol, date: { - gte: startDate + in: dates } } }) @@ -266,17 +286,7 @@ export class BenchmarkService { return { marketData }; } - const step = Math.round( - marketDataItems.length / Math.min(marketDataItems.length, MAX_CHART_ITEMS) - ); - - let i = 0; - for (let marketDataItem of marketDataItems) { - if (i % step !== 0) { - continue; - } - const exchangeRate = exchangeRates[`${currentSymbolItem.currency}${userCurrency}`]?.[ format(marketDataItem.date, DATE_FORMAT) @@ -299,15 +309,12 @@ export class BenchmarkService { }); } - const includesToday = isSameDay( - parseDate(last(marketData).date), - new Date() - ); + const includesToday = isSameDay(parseDate(last(marketData).date), endDate); if (currentSymbolItem?.marketPrice && !includesToday) { const exchangeRate = exchangeRates[`${currentSymbolItem.currency}${userCurrency}`]?.[ - format(new Date(), DATE_FORMAT) + format(endDate, DATE_FORMAT) ]; const exchangeRateFactor = @@ -316,7 +323,7 @@ export class BenchmarkService { : 1; marketData.push({ - date: format(new Date(), DATE_FORMAT), + date: format(endDate, DATE_FORMAT), value: this.calculateChangeInPercentage( marketPriceAtStartDate, diff --git a/apps/api/src/app/portfolio/portfolio-calculator.ts b/apps/api/src/app/portfolio/portfolio-calculator.ts index e7ded8f8c..a519b91cf 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator.ts @@ -18,6 +18,7 @@ import { addDays, addMilliseconds, differenceInDays, + eachDayOfInterval, endOfDay, format, isBefore, @@ -199,16 +200,10 @@ export class PortfolioCalculator { }) ?? []; const currencies: { [symbol: string]: string } = {}; - const dates: Date[] = []; const dataGatheringItems: IDataGatheringItem[] = []; const firstIndex = transactionPointsBeforeEndDate.length; - let day = start; - - while (isBefore(day, end)) { - dates.push(resetHours(day)); - day = addDays(day, step); - } + const dates = eachDayOfInterval({ start, end }, { step }); if (!isSameDay(last(dates), end)) { dates.push(resetHours(end)); diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 3517b8975..ce5fc998f 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -1482,17 +1482,13 @@ export class PortfolioService { userId = await this.getUserId(impersonationId, userId); - const endDate = new Date(); - const portfolioStart = parseDate(transactionPoints[0].date); const startDate = this.getStartDate(dateRange, portfolioStart); - - let step = 1; - - if (withDataDecimation) { - const daysInMarket = differenceInDays(new Date(), startDate); - step = Math.round(daysInMarket / Math.min(daysInMarket, MAX_CHART_ITEMS)); - } + const endDate = new Date(); + 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,