parent
b8626c2086
commit
4e7b7375a9
@ -0,0 +1,85 @@
|
||||
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
|
||||
import { DataEnhancerInterface } from '@ghostfolio/api/services/data-provider/interfaces/data-enhancer.interface';
|
||||
import { DEFAULT_REQUEST_TIMEOUT } from '@ghostfolio/common/config';
|
||||
import { parseSymbol } from '@ghostfolio/common/helper';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { SymbolProfile } from '@prisma/client';
|
||||
import got, { Headers } from 'got';
|
||||
|
||||
@Injectable()
|
||||
export class OpenFigiDataEnhancerService implements DataEnhancerInterface {
|
||||
private static baseUrl = 'https://api.openfigi.com';
|
||||
|
||||
public constructor(
|
||||
private readonly configurationService: ConfigurationService
|
||||
) {}
|
||||
|
||||
public async enhance({
|
||||
response,
|
||||
symbol
|
||||
}: {
|
||||
response: Partial<SymbolProfile>;
|
||||
symbol: string;
|
||||
}): Promise<Partial<SymbolProfile>> {
|
||||
if (
|
||||
!(
|
||||
response.assetClass === 'EQUITY' &&
|
||||
(response.assetSubClass === 'ETF' || response.assetSubClass === 'STOCK')
|
||||
)
|
||||
) {
|
||||
return response;
|
||||
}
|
||||
|
||||
const headers: Headers = {};
|
||||
const { exchange, ticker } = parseSymbol({
|
||||
symbol,
|
||||
dataSource: response.dataSource
|
||||
});
|
||||
|
||||
if (this.configurationService.get('OPEN_FIGI_API_KEY')) {
|
||||
headers['X-OPENFIGI-APIKEY'] =
|
||||
this.configurationService.get('OPEN_FIGI_API_KEY');
|
||||
}
|
||||
|
||||
let abortController = new AbortController();
|
||||
|
||||
setTimeout(() => {
|
||||
abortController.abort();
|
||||
}, DEFAULT_REQUEST_TIMEOUT);
|
||||
|
||||
const mappings = await got
|
||||
.post(`${OpenFigiDataEnhancerService.baseUrl}/v3/mapping`, {
|
||||
headers,
|
||||
json: [{ exchCode: exchange, idType: 'TICKER', idValue: ticker }],
|
||||
// @ts-ignore
|
||||
signal: abortController.signal
|
||||
})
|
||||
.json<any[]>();
|
||||
|
||||
if (mappings?.length === 1 && mappings[0].data?.length === 1) {
|
||||
const { compositeFIGI, figi, shareClassFIGI } = mappings[0].data[0];
|
||||
|
||||
if (figi) {
|
||||
response.figi = figi;
|
||||
}
|
||||
|
||||
if (compositeFIGI) {
|
||||
response.figiComposite = compositeFIGI;
|
||||
}
|
||||
|
||||
if (shareClassFIGI) {
|
||||
response.figiShareClass = shareClassFIGI;
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public getName() {
|
||||
return 'OPENFIGI';
|
||||
}
|
||||
|
||||
public getTestSymbol() {
|
||||
return undefined;
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "SymbolProfile"
|
||||
ADD COLUMN "figi" TEXT,
|
||||
ADD COLUMN "figiComposite" TEXT,
|
||||
ADD COLUMN "figiShareClass" TEXT;
|
Loading…
Reference in new issue