mirror of https://github.com/ghostfolio/ghostfolio
Thomas Kaul
1 year ago
committed by
GitHub
10 changed files with 136 additions and 1 deletions
@ -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