2021-12-04 11:49:00 +01:00
|
|
|
import { HistoricalDataItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-position-detail.interface';
|
2021-08-14 16:55:40 +02:00
|
|
|
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
|
2021-09-18 19:32:22 +02:00
|
|
|
import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
|
2021-12-04 11:49:00 +01:00
|
|
|
import { MarketDataService } from '@ghostfolio/api/services/market-data.service';
|
2021-08-09 21:33:58 +02:00
|
|
|
import { PrismaService } from '@ghostfolio/api/services/prisma.service';
|
2021-11-07 21:25:18 +01:00
|
|
|
import { Injectable, Logger } from '@nestjs/common';
|
2021-09-24 21:09:48 +02:00
|
|
|
import { DataSource } from '@prisma/client';
|
2021-12-04 11:49:00 +01:00
|
|
|
import { subDays } from 'date-fns';
|
2021-04-13 21:53:58 +02:00
|
|
|
|
|
|
|
import { LookupItem } from './interfaces/lookup-item.interface';
|
|
|
|
import { SymbolItem } from './interfaces/symbol-item.interface';
|
|
|
|
|
|
|
|
@Injectable()
|
|
|
|
export class SymbolService {
|
|
|
|
public constructor(
|
2021-04-27 21:03:22 +02:00
|
|
|
private readonly dataProviderService: DataProviderService,
|
2021-12-04 11:49:00 +01:00
|
|
|
private readonly marketDataService: MarketDataService,
|
2021-08-09 21:33:58 +02:00
|
|
|
private readonly prismaService: PrismaService
|
2021-04-13 21:53:58 +02:00
|
|
|
) {}
|
|
|
|
|
2021-12-04 11:49:00 +01:00
|
|
|
public async get({
|
|
|
|
dataGatheringItem,
|
|
|
|
includeHistoricalData = false
|
|
|
|
}: {
|
|
|
|
dataGatheringItem: IDataGatheringItem;
|
|
|
|
includeHistoricalData?: boolean;
|
|
|
|
}): Promise<SymbolItem> {
|
2021-09-18 19:32:22 +02:00
|
|
|
const response = await this.dataProviderService.get([dataGatheringItem]);
|
|
|
|
const { currency, marketPrice } = response[dataGatheringItem.symbol] ?? {};
|
2021-04-13 21:53:58 +02:00
|
|
|
|
2021-09-18 19:32:22 +02:00
|
|
|
if (dataGatheringItem.dataSource && marketPrice) {
|
2021-12-04 11:49:00 +01:00
|
|
|
let historicalData: HistoricalDataItem[];
|
|
|
|
|
|
|
|
if (includeHistoricalData) {
|
2021-12-07 19:10:40 +01:00
|
|
|
const days = 10;
|
2021-12-04 11:49:00 +01:00
|
|
|
|
|
|
|
const marketData = await this.marketDataService.getRange({
|
|
|
|
dateQuery: { gte: subDays(new Date(), days) },
|
|
|
|
symbols: [dataGatheringItem.symbol]
|
|
|
|
});
|
|
|
|
|
|
|
|
historicalData = marketData.map(({ date, marketPrice }) => {
|
|
|
|
return {
|
|
|
|
date: date.toISOString(),
|
|
|
|
value: marketPrice
|
|
|
|
};
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-08-30 18:08:21 +02:00
|
|
|
return {
|
2021-09-24 21:09:48 +02:00
|
|
|
currency,
|
2021-12-04 11:49:00 +01:00
|
|
|
historicalData,
|
2021-08-30 18:08:21 +02:00
|
|
|
marketPrice,
|
2021-09-18 19:32:22 +02:00
|
|
|
dataSource: dataGatheringItem.dataSource
|
2021-08-30 18:08:21 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return undefined;
|
2021-04-13 21:53:58 +02:00
|
|
|
}
|
|
|
|
|
2021-05-20 20:36:08 +02:00
|
|
|
public async lookup(aQuery: string): Promise<{ items: LookupItem[] }> {
|
|
|
|
const results: { items: LookupItem[] } = { items: [] };
|
2021-04-27 21:03:22 +02:00
|
|
|
|
2021-05-20 20:36:08 +02:00
|
|
|
if (!aQuery) {
|
2021-04-27 21:03:22 +02:00
|
|
|
return results;
|
|
|
|
}
|
|
|
|
|
2021-04-13 21:53:58 +02:00
|
|
|
try {
|
2021-05-20 20:36:08 +02:00
|
|
|
const { items } = await this.dataProviderService.search(aQuery);
|
|
|
|
results.items = items;
|
|
|
|
|
|
|
|
// Add custom symbols
|
2021-08-09 21:33:58 +02:00
|
|
|
const ghostfolioSymbolProfiles =
|
|
|
|
await this.prismaService.symbolProfile.findMany({
|
|
|
|
select: {
|
2021-08-14 11:06:21 +02:00
|
|
|
currency: true,
|
2021-08-09 21:33:58 +02:00
|
|
|
dataSource: true,
|
|
|
|
name: true,
|
|
|
|
symbol: true
|
|
|
|
},
|
|
|
|
where: {
|
|
|
|
AND: [
|
|
|
|
{
|
|
|
|
dataSource: DataSource.GHOSTFOLIO,
|
|
|
|
name: {
|
|
|
|
startsWith: aQuery
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
for (const ghostfolioSymbolProfile of ghostfolioSymbolProfiles) {
|
|
|
|
results.items.push(ghostfolioSymbolProfile);
|
|
|
|
}
|
2021-04-13 21:53:58 +02:00
|
|
|
|
2021-05-20 20:36:08 +02:00
|
|
|
return results;
|
2021-04-13 21:53:58 +02:00
|
|
|
} catch (error) {
|
2021-11-07 21:25:18 +01:00
|
|
|
Logger.error(error);
|
2021-04-13 21:53:58 +02:00
|
|
|
|
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|