Browse Source

feat: extend the benchmark

pull/2575/head
Dhoni77 2 years ago
committed by Thomas
parent
commit
07fac08405
  1. 64
      apps/api/src/app/benchmark/benchmark.service.ts
  2. 4
      apps/api/src/services/market-data/market-data.service.ts

64
apps/api/src/app/benchmark/benchmark.service.ts

@ -9,17 +9,21 @@ import {
MAX_CHART_ITEMS,
PROPERTY_BENCHMARKS
} from '@ghostfolio/common/config';
import { DATE_FORMAT } from '@ghostfolio/common/helper';
import {
DATE_FORMAT,
calculateBenchmarkTrend,
} from '@ghostfolio/common/helper';
import {
BenchmarkMarketDataDetails,
BenchmarkProperty,
BenchmarkResponse,
UniqueAsset
} from '@ghostfolio/common/interfaces';
import { Injectable } from '@nestjs/common';
import { SymbolProfile } from '@prisma/client';
import { BenchmarkTrend } from '@ghostfolio/common/types/benchmark-trend-type.type';
import { Injectable, Logger } from '@nestjs/common';
import { DataSource, SymbolProfile } from '@prisma/client';
import Big from 'big.js';
import { format } from 'date-fns';
import { format, subDays } from 'date-fns';
import { uniqBy } from 'lodash';
import ms from 'ms';
@ -35,7 +39,7 @@ export class BenchmarkService {
private readonly redisCacheService: RedisCacheService,
private readonly symbolProfileService: SymbolProfileService,
private readonly symbolService: SymbolService
) {}
) { }
public calculateChangeInPercentage(baseValue: number, currentValue: number) {
if (baseValue && currentValue) {
@ -45,6 +49,31 @@ export class BenchmarkService {
return 0;
}
public async getBenchMarkTrends(dataSource: DataSource, symbol: string) {
return this.marketDataService
.marketDataItems({
orderBy: {
date: 'desc'
},
select: {
date: true,
marketPrice: true
},
where: {
dataSource,
symbol,
date: { gte: subDays(new Date(), 400) }
}
})
.then((historicalData) => {
const fiftyDayAvg = calculateBenchmarkTrend(historicalData, 50);
const twoHundrredDayAvg = calculateBenchmarkTrend(historicalData, 200);
Logger.debug(`50d: ${fiftyDayAvg} and 200d: ${twoHundrredDayAvg}`);
return { trend200d: twoHundrredDayAvg, trend50d: fiftyDayAvg };
});
}
public async getBenchmarks({ useCache = true } = {}): Promise<
BenchmarkResponse['benchmarks']
> {
@ -59,12 +88,16 @@ export class BenchmarkService {
if (benchmarks) {
return benchmarks;
}
} catch {}
} catch { }
}
const benchmarkAssetProfiles = await this.getBenchmarkAssetProfiles();
const promises: Promise<{ date: Date; marketPrice: number }>[] = [];
const movingAvgPromises: Promise<{
trend50d: BenchmarkTrend;
trend200d: BenchmarkTrend;
}>[] = [];
const quotes = await this.dataProviderService.getQuotes({
items: benchmarkAssetProfiles.map(({ dataSource, symbol }) => {
@ -74,9 +107,13 @@ export class BenchmarkService {
for (const { dataSource, symbol } of benchmarkAssetProfiles) {
promises.push(this.marketDataService.getMax({ dataSource, symbol }));
movingAvgPromises.push(this.getBenchMarkTrends(dataSource, symbol));
}
const allTimeHighs = await Promise.all(promises);
const [allTimeHighs, benchmarkTrends] = await Promise.all([
Promise.all(promises),
Promise.all(movingAvgPromises)
]);
let storeInCache = true;
benchmarks = allTimeHighs.map((allTimeHigh, index) => {
@ -93,6 +130,7 @@ export class BenchmarkService {
} else {
storeInCache = false;
}
return {
marketCondition: this.getMarketCondition(
performancePercentFromAllTimeHigh
@ -100,8 +138,10 @@ export class BenchmarkService {
name: benchmarkAssetProfiles[index].name,
performances: {
allTimeHigh: {
date: allTimeHigh.date,
performancePercent: performancePercentFromAllTimeHigh
date: allTimeHigh?.date || new Date(),
performancePercent: performancePercentFromAllTimeHigh,
trend50d: benchmarkTrends[index].trend50d,
trend200d: benchmarkTrends[index].trend200d
}
}
};
@ -186,9 +226,9 @@ export class BenchmarkService {
marketPriceAtStartDate === 0
? 0
: this.calculateChangeInPercentage(
marketPriceAtStartDate,
marketDataItem.marketPrice
) * 100
marketPriceAtStartDate,
marketDataItem.marketPrice
) * 100
};
})
]

4
apps/api/src/services/market-data/market-data.service.ts

@ -90,15 +90,17 @@ export class MarketDataService {
}
public async marketDataItems(params: {
select?: Prisma.MarketDataSelectScalar;
skip?: number;
take?: number;
cursor?: Prisma.MarketDataWhereUniqueInput;
where?: Prisma.MarketDataWhereInput;
orderBy?: Prisma.MarketDataOrderByWithRelationInput;
}): Promise<MarketData[]> {
const { skip, take, cursor, where, orderBy } = params;
const { select, skip, take, cursor, where, orderBy } = params;
return this.prismaService.marketData.findMany({
select,
cursor,
orderBy,
skip,

Loading…
Cancel
Save