2021-05-27 20:50:10 +02:00
|
|
|
import {
|
2021-07-28 16:11:19 +02:00
|
|
|
DATE_FORMAT,
|
2021-05-27 20:50:10 +02:00
|
|
|
getToday,
|
|
|
|
getYesterday,
|
|
|
|
isRakutenRapidApiSymbol
|
|
|
|
} from '@ghostfolio/common/helper';
|
2021-05-16 22:11:14 +02:00
|
|
|
import { Granularity } from '@ghostfolio/common/types';
|
2021-04-13 21:53:58 +02:00
|
|
|
import { Injectable } from '@nestjs/common';
|
2021-05-01 12:30:52 +02:00
|
|
|
import { DataSource } from '@prisma/client';
|
2021-04-13 21:53:58 +02:00
|
|
|
import * as bent from 'bent';
|
|
|
|
import { format, subMonths, subWeeks, subYears } from 'date-fns';
|
|
|
|
|
2021-04-18 19:06:54 +02:00
|
|
|
import { ConfigurationService } from '../../configuration.service';
|
2021-04-13 21:53:58 +02:00
|
|
|
import { DataProviderInterface } from '../../interfaces/data-provider.interface';
|
|
|
|
import {
|
|
|
|
IDataProviderHistoricalResponse,
|
2021-04-22 22:00:46 +02:00
|
|
|
IDataProviderResponse,
|
|
|
|
MarketState
|
2021-04-13 21:53:58 +02:00
|
|
|
} from '../../interfaces/interfaces';
|
|
|
|
import { PrismaService } from '../../prisma.service';
|
|
|
|
|
|
|
|
@Injectable()
|
|
|
|
export class RakutenRapidApiService implements DataProviderInterface {
|
|
|
|
public static FEAR_AND_GREED_INDEX_NAME = 'Fear & Greed Index';
|
|
|
|
|
2021-08-07 22:38:07 +02:00
|
|
|
private prismaService: PrismaService;
|
2021-04-13 21:53:58 +02:00
|
|
|
|
2021-04-18 19:06:54 +02:00
|
|
|
public constructor(
|
|
|
|
private readonly configurationService: ConfigurationService
|
|
|
|
) {}
|
2021-04-13 21:53:58 +02:00
|
|
|
|
2021-05-27 20:50:10 +02:00
|
|
|
public canHandle(symbol: string) {
|
|
|
|
return (
|
|
|
|
isRakutenRapidApiSymbol(symbol) &&
|
2021-05-27 21:12:55 +02:00
|
|
|
!!this.configurationService.get('RAKUTEN_RAPID_API_KEY')
|
2021-05-27 20:50:10 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-04-13 21:53:58 +02:00
|
|
|
public async get(
|
|
|
|
aSymbols: string[]
|
|
|
|
): Promise<{ [symbol: string]: IDataProviderResponse }> {
|
|
|
|
if (aSymbols.length <= 0) {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
const symbol = aSymbols[0];
|
|
|
|
|
|
|
|
if (symbol === 'GF.FEAR_AND_GREED_INDEX') {
|
|
|
|
const fgi = await this.getFearAndGreedIndex();
|
|
|
|
|
|
|
|
return {
|
|
|
|
'GF.FEAR_AND_GREED_INDEX': {
|
|
|
|
currency: undefined,
|
2021-04-28 21:30:49 +02:00
|
|
|
dataSource: DataSource.RAKUTEN,
|
2021-04-13 21:53:58 +02:00
|
|
|
marketPrice: fgi.now.value,
|
2021-04-22 22:00:46 +02:00
|
|
|
marketState: MarketState.open,
|
2021-04-13 21:53:58 +02:00
|
|
|
name: RakutenRapidApiService.FEAR_AND_GREED_INDEX_NAME
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
}
|
|
|
|
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
public async getHistorical(
|
|
|
|
aSymbols: string[],
|
|
|
|
aGranularity: Granularity = 'day',
|
|
|
|
from: Date,
|
|
|
|
to: Date
|
|
|
|
): Promise<{
|
|
|
|
[symbol: string]: { [date: string]: IDataProviderHistoricalResponse };
|
|
|
|
}> {
|
|
|
|
if (aSymbols.length <= 0) {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
const symbol = aSymbols[0];
|
|
|
|
|
|
|
|
if (symbol === 'GF.FEAR_AND_GREED_INDEX') {
|
|
|
|
const fgi = await this.getFearAndGreedIndex();
|
|
|
|
|
|
|
|
try {
|
|
|
|
// Rebuild historical data
|
|
|
|
// TODO: can be removed after all data from the last year has been gathered
|
|
|
|
// (introduced on 27.03.2021)
|
|
|
|
|
2021-08-07 22:38:07 +02:00
|
|
|
await this.prismaService.marketData.create({
|
2021-04-13 21:53:58 +02:00
|
|
|
data: {
|
|
|
|
symbol,
|
|
|
|
date: subWeeks(getToday(), 1),
|
|
|
|
marketPrice: fgi.oneWeekAgo.value
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-08-07 22:38:07 +02:00
|
|
|
await this.prismaService.marketData.create({
|
2021-04-13 21:53:58 +02:00
|
|
|
data: {
|
|
|
|
symbol,
|
|
|
|
date: subMonths(getToday(), 1),
|
|
|
|
marketPrice: fgi.oneMonthAgo.value
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-08-07 22:38:07 +02:00
|
|
|
await this.prismaService.marketData.create({
|
2021-04-13 21:53:58 +02:00
|
|
|
data: {
|
|
|
|
symbol,
|
|
|
|
date: subYears(getToday(), 1),
|
|
|
|
marketPrice: fgi.oneYearAgo.value
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
} catch {}
|
|
|
|
|
|
|
|
return {
|
|
|
|
'GF.FEAR_AND_GREED_INDEX': {
|
2021-07-28 16:11:19 +02:00
|
|
|
[format(getYesterday(), DATE_FORMAT)]: {
|
2021-04-13 21:53:58 +02:00
|
|
|
marketPrice: fgi.previousClose.value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
} catch (error) {}
|
|
|
|
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2021-05-20 20:36:08 +02:00
|
|
|
public async search(aSymbol: string) {
|
|
|
|
return { items: [] };
|
|
|
|
}
|
|
|
|
|
|
|
|
public setPrisma(aPrismaService: PrismaService) {
|
2021-08-07 22:38:07 +02:00
|
|
|
this.prismaService = aPrismaService;
|
2021-05-20 20:36:08 +02:00
|
|
|
}
|
|
|
|
|
2021-04-13 21:53:58 +02:00
|
|
|
private async getFearAndGreedIndex(): Promise<{
|
|
|
|
now: { value: number; valueText: string };
|
|
|
|
previousClose: { value: number; valueText: string };
|
|
|
|
oneWeekAgo: { value: number; valueText: string };
|
|
|
|
oneMonthAgo: { value: number; valueText: string };
|
|
|
|
oneYearAgo: { value: number; valueText: string };
|
|
|
|
}> {
|
|
|
|
try {
|
|
|
|
const get = bent(
|
|
|
|
`https://fear-and-greed-index.p.rapidapi.com/v1/fgi`,
|
|
|
|
'GET',
|
|
|
|
'json',
|
|
|
|
200,
|
|
|
|
{
|
|
|
|
useQueryString: true,
|
|
|
|
'x-rapidapi-host': 'fear-and-greed-index.p.rapidapi.com',
|
2021-04-18 19:06:54 +02:00
|
|
|
'x-rapidapi-key': this.configurationService.get(
|
|
|
|
'RAKUTEN_RAPID_API_KEY'
|
|
|
|
)
|
2021-04-13 21:53:58 +02:00
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
const { fgi } = await get();
|
|
|
|
return fgi;
|
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|