|
|
|
@ -12,6 +12,7 @@ import {
|
|
|
|
|
UniqueAsset
|
|
|
|
|
} from '@ghostfolio/common/interfaces';
|
|
|
|
|
import { Injectable } from '@nestjs/common';
|
|
|
|
|
import { SymbolProfile } from '@prisma/client';
|
|
|
|
|
import Big from 'big.js';
|
|
|
|
|
import { format } from 'date-fns';
|
|
|
|
|
import ms from 'ms';
|
|
|
|
@ -55,25 +56,25 @@ export class BenchmarkService {
|
|
|
|
|
} catch {}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const benchmarkAssets: UniqueAsset[] =
|
|
|
|
|
((await this.propertyService.getByKey(
|
|
|
|
|
PROPERTY_BENCHMARKS
|
|
|
|
|
)) as UniqueAsset[]) ?? [];
|
|
|
|
|
const benchmarkAssetProfiles = await this.getBenchmarkAssetProfiles();
|
|
|
|
|
|
|
|
|
|
const promises: Promise<number>[] = [];
|
|
|
|
|
|
|
|
|
|
const [quotes, assetProfiles] = await Promise.all([
|
|
|
|
|
this.dataProviderService.getQuotes(benchmarkAssets),
|
|
|
|
|
this.symbolProfileService.getSymbolProfiles(benchmarkAssets)
|
|
|
|
|
]);
|
|
|
|
|
const quotes = await this.dataProviderService.getQuotes(
|
|
|
|
|
benchmarkAssetProfiles.map(({ dataSource, symbol }) => {
|
|
|
|
|
return { dataSource, symbol };
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
for (const benchmarkAsset of benchmarkAssets) {
|
|
|
|
|
promises.push(this.marketDataService.getMax(benchmarkAsset));
|
|
|
|
|
for (const { dataSource, symbol } of benchmarkAssetProfiles) {
|
|
|
|
|
promises.push(this.marketDataService.getMax({ dataSource, symbol }));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const allTimeHighs = await Promise.all(promises);
|
|
|
|
|
|
|
|
|
|
benchmarks = allTimeHighs.map((allTimeHigh, index) => {
|
|
|
|
|
const { marketPrice } = quotes[benchmarkAssets[index].symbol] ?? {};
|
|
|
|
|
const { marketPrice } =
|
|
|
|
|
quotes[benchmarkAssetProfiles[index].symbol] ?? {};
|
|
|
|
|
|
|
|
|
|
let performancePercentFromAllTimeHigh = 0;
|
|
|
|
|
|
|
|
|
@ -88,12 +89,7 @@ export class BenchmarkService {
|
|
|
|
|
marketCondition: this.getMarketCondition(
|
|
|
|
|
performancePercentFromAllTimeHigh
|
|
|
|
|
),
|
|
|
|
|
name: assetProfiles.find(({ dataSource, symbol }) => {
|
|
|
|
|
return (
|
|
|
|
|
dataSource === benchmarkAssets[index].dataSource &&
|
|
|
|
|
symbol === benchmarkAssets[index].symbol
|
|
|
|
|
);
|
|
|
|
|
})?.name,
|
|
|
|
|
name: benchmarkAssetProfiles[index].name,
|
|
|
|
|
performances: {
|
|
|
|
|
allTimeHigh: {
|
|
|
|
|
performancePercent: performancePercentFromAllTimeHigh
|
|
|
|
@ -111,19 +107,23 @@ export class BenchmarkService {
|
|
|
|
|
return benchmarks;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async getBenchmarkAssetProfiles(): Promise<UniqueAsset[]> {
|
|
|
|
|
const benchmarkAssets: UniqueAsset[] =
|
|
|
|
|
((await this.propertyService.getByKey(
|
|
|
|
|
PROPERTY_BENCHMARKS
|
|
|
|
|
)) as UniqueAsset[]) ?? [];
|
|
|
|
|
public async getBenchmarkAssetProfiles(): Promise<Partial<SymbolProfile>[]> {
|
|
|
|
|
const symbolProfileIds: string[] = (
|
|
|
|
|
((await this.propertyService.getByKey(PROPERTY_BENCHMARKS)) as {
|
|
|
|
|
symbolProfileId: string;
|
|
|
|
|
}[]) ?? []
|
|
|
|
|
).map(({ symbolProfileId }) => {
|
|
|
|
|
return symbolProfileId;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const assetProfiles = await this.symbolProfileService.getSymbolProfiles(
|
|
|
|
|
benchmarkAssets
|
|
|
|
|
);
|
|
|
|
|
const assetProfiles =
|
|
|
|
|
await this.symbolProfileService.getSymbolProfilesByIds(symbolProfileIds);
|
|
|
|
|
|
|
|
|
|
return assetProfiles.map(({ dataSource, symbol }) => {
|
|
|
|
|
return assetProfiles.map(({ dataSource, id, name, symbol }) => {
|
|
|
|
|
return {
|
|
|
|
|
dataSource,
|
|
|
|
|
id,
|
|
|
|
|
name,
|
|
|
|
|
symbol
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|