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 { import {
DATE_FORMAT, DATE_FORMAT,
calculateBenchmarkTrend, calculateBenchmarkTrend,
parseDate parseDate,
resetHours
} from '@ghostfolio/common/helper'; } from '@ghostfolio/common/helper';
import { import {
Benchmark, Benchmark,
@ -27,7 +28,13 @@ import { BenchmarkTrend } from '@ghostfolio/common/types';
import { Injectable, Logger } from '@nestjs/common'; import { Injectable, Logger } from '@nestjs/common';
import { SymbolProfile } from '@prisma/client'; import { SymbolProfile } from '@prisma/client';
import { Big } from 'big.js'; 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 { isNumber, last, uniqBy } from 'lodash';
import ms from 'ms'; import ms from 'ms';
@ -209,14 +216,27 @@ export class BenchmarkService {
public async getMarketDataBySymbol({ public async getMarketDataBySymbol({
dataSource, dataSource,
startDate, startDate,
endDate = new Date(),
symbol, symbol,
userCurrency userCurrency
}: { }: {
startDate: Date; startDate: Date;
endDate?: Date;
userCurrency: string; userCurrency: string;
} & UniqueAsset): Promise<BenchmarkMarketDataDetails> { } & UniqueAsset): Promise<BenchmarkMarketDataDetails> {
const marketData: { date: string; value: number }[] = []; 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([ const [currentSymbolItem, marketDataItems] = await Promise.all([
this.symbolService.get({ this.symbolService.get({
dataGatheringItem: { dataGatheringItem: {
@ -232,7 +252,7 @@ export class BenchmarkService {
dataSource, dataSource,
symbol, symbol,
date: { date: {
gte: startDate in: dates
} }
} }
}) })
@ -266,17 +286,7 @@ export class BenchmarkService {
return { marketData }; return { marketData };
} }
const step = Math.round(
marketDataItems.length / Math.min(marketDataItems.length, MAX_CHART_ITEMS)
);
let i = 0;
for (let marketDataItem of marketDataItems) { for (let marketDataItem of marketDataItems) {
if (i % step !== 0) {
continue;
}
const exchangeRate = const exchangeRate =
exchangeRates[`${currentSymbolItem.currency}${userCurrency}`]?.[ exchangeRates[`${currentSymbolItem.currency}${userCurrency}`]?.[
format(marketDataItem.date, DATE_FORMAT) format(marketDataItem.date, DATE_FORMAT)
@ -299,15 +309,12 @@ export class BenchmarkService {
}); });
} }
const includesToday = isSameDay( const includesToday = isSameDay(parseDate(last(marketData).date), endDate);
parseDate(last(marketData).date),
new Date()
);
if (currentSymbolItem?.marketPrice && !includesToday) { if (currentSymbolItem?.marketPrice && !includesToday) {
const exchangeRate = const exchangeRate =
exchangeRates[`${currentSymbolItem.currency}${userCurrency}`]?.[ exchangeRates[`${currentSymbolItem.currency}${userCurrency}`]?.[
format(new Date(), DATE_FORMAT) format(endDate, DATE_FORMAT)
]; ];
const exchangeRateFactor = const exchangeRateFactor =
@ -316,7 +323,7 @@ export class BenchmarkService {
: 1; : 1;
marketData.push({ marketData.push({
date: format(new Date(), DATE_FORMAT), date: format(endDate, DATE_FORMAT),
value: value:
this.calculateChangeInPercentage( this.calculateChangeInPercentage(
marketPriceAtStartDate, marketPriceAtStartDate,

9
apps/api/src/app/portfolio/portfolio-calculator.ts

@ -18,6 +18,7 @@ import {
addDays, addDays,
addMilliseconds, addMilliseconds,
differenceInDays, differenceInDays,
eachDayOfInterval,
endOfDay, endOfDay,
format, format,
isBefore, isBefore,
@ -199,16 +200,10 @@ export class PortfolioCalculator {
}) ?? []; }) ?? [];
const currencies: { [symbol: string]: string } = {}; const currencies: { [symbol: string]: string } = {};
const dates: Date[] = [];
const dataGatheringItems: IDataGatheringItem[] = []; const dataGatheringItems: IDataGatheringItem[] = [];
const firstIndex = transactionPointsBeforeEndDate.length; const firstIndex = transactionPointsBeforeEndDate.length;
let day = start; const dates = eachDayOfInterval({ start, end }, { step });
while (isBefore(day, end)) {
dates.push(resetHours(day));
day = addDays(day, step);
}
if (!isSameDay(last(dates), end)) { if (!isSameDay(last(dates), end)) {
dates.push(resetHours(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); userId = await this.getUserId(impersonationId, userId);
const endDate = new Date();
const portfolioStart = parseDate(transactionPoints[0].date); const portfolioStart = parseDate(transactionPoints[0].date);
const startDate = this.getStartDate(dateRange, portfolioStart); const startDate = this.getStartDate(dateRange, portfolioStart);
const endDate = new Date();
let step = 1; const daysInMarket = differenceInDays(endDate, startDate) + 1;
const step = withDataDecimation
if (withDataDecimation) { ? Math.round(daysInMarket / Math.min(daysInMarket, MAX_CHART_ITEMS))
const daysInMarket = differenceInDays(new Date(), startDate); : 1;
step = Math.round(daysInMarket / Math.min(daysInMarket, MAX_CHART_ITEMS));
}
const items = await portfolioCalculator.getChartData({ const items = await portfolioCalculator.getChartData({
step, step,

Loading…
Cancel
Save