|
|
@ -2,6 +2,7 @@ import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.s |
|
|
|
import { SymbolService } from '@ghostfolio/api/app/symbol/symbol.service'; |
|
|
|
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; |
|
|
|
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; |
|
|
|
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; |
|
|
|
import { PropertyService } from '@ghostfolio/api/services/property/property.service'; |
|
|
|
import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; |
|
|
|
import { |
|
|
@ -11,6 +12,7 @@ import { |
|
|
|
import { DATE_FORMAT } from '@ghostfolio/common/helper'; |
|
|
|
import { |
|
|
|
BenchmarkMarketDataDetails, |
|
|
|
BenchmarkProperty, |
|
|
|
BenchmarkResponse, |
|
|
|
UniqueAsset |
|
|
|
} from '@ghostfolio/common/interfaces'; |
|
|
@ -18,6 +20,7 @@ import { Injectable } from '@nestjs/common'; |
|
|
|
import { SymbolProfile } from '@prisma/client'; |
|
|
|
import Big from 'big.js'; |
|
|
|
import { format } from 'date-fns'; |
|
|
|
import { uniqBy } from 'lodash'; |
|
|
|
import ms from 'ms'; |
|
|
|
|
|
|
|
@Injectable() |
|
|
@ -27,6 +30,7 @@ export class BenchmarkService { |
|
|
|
public constructor( |
|
|
|
private readonly dataProviderService: DataProviderService, |
|
|
|
private readonly marketDataService: MarketDataService, |
|
|
|
private readonly prismaService: PrismaService, |
|
|
|
private readonly propertyService: PropertyService, |
|
|
|
private readonly redisCacheService: RedisCacheService, |
|
|
|
private readonly symbolProfileService: SymbolProfileService, |
|
|
@ -116,9 +120,9 @@ export class BenchmarkService { |
|
|
|
|
|
|
|
public async getBenchmarkAssetProfiles(): Promise<Partial<SymbolProfile>[]> { |
|
|
|
const symbolProfileIds: string[] = ( |
|
|
|
((await this.propertyService.getByKey(PROPERTY_BENCHMARKS)) as { |
|
|
|
symbolProfileId: string; |
|
|
|
}[]) ?? [] |
|
|
|
((await this.propertyService.getByKey( |
|
|
|
PROPERTY_BENCHMARKS |
|
|
|
)) as BenchmarkProperty[]) ?? [] |
|
|
|
).map(({ symbolProfileId }) => { |
|
|
|
return symbolProfileId; |
|
|
|
}); |
|
|
@ -204,6 +208,43 @@ export class BenchmarkService { |
|
|
|
return response; |
|
|
|
} |
|
|
|
|
|
|
|
public async addBenchmark({ |
|
|
|
dataSource, |
|
|
|
symbol |
|
|
|
}: UniqueAsset): Promise<Partial<SymbolProfile>> { |
|
|
|
const assetProfile = await this.prismaService.symbolProfile.findFirst({ |
|
|
|
where: { |
|
|
|
dataSource, |
|
|
|
symbol |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
if (!assetProfile) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
let benchmarks = |
|
|
|
((await this.propertyService.getByKey( |
|
|
|
PROPERTY_BENCHMARKS |
|
|
|
)) as BenchmarkProperty[]) ?? []; |
|
|
|
|
|
|
|
benchmarks.push({ symbolProfileId: assetProfile.id }); |
|
|
|
|
|
|
|
benchmarks = uniqBy(benchmarks, 'symbolProfileId'); |
|
|
|
|
|
|
|
await this.propertyService.put({ |
|
|
|
key: PROPERTY_BENCHMARKS, |
|
|
|
value: JSON.stringify(benchmarks) |
|
|
|
}); |
|
|
|
|
|
|
|
return { |
|
|
|
dataSource, |
|
|
|
symbol, |
|
|
|
id: assetProfile.id, |
|
|
|
name: assetProfile.name |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
private getMarketCondition(aPerformanceInPercent: number) { |
|
|
|
return aPerformanceInPercent <= -0.2 ? 'BEAR_MARKET' : 'NEUTRAL_MARKET'; |
|
|
|
} |
|
|
|