Browse Source

Update benchmark service to use same market dates as portfolio

Refactor based on comments
pull/3167/head
helgehatt 1 year ago
committed by Thomas Kaul
parent
commit
7200c538a0
  1. 45
      apps/api/src/app/benchmark/benchmark.service.ts
  2. 9
      apps/api/src/app/portfolio/portfolio-calculator.ts
  3. 14
      apps/api/src/app/portfolio/portfolio.service.ts

45
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<BenchmarkMarketDataDetails> {
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,

9
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));

14
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,

Loading…
Cancel
Save