|
|
|
@ -5,6 +5,7 @@ import { |
|
|
|
GetAssetProfileParams, |
|
|
|
GetDividendsParams, |
|
|
|
GetHistoricalParams, |
|
|
|
GetMarketDataOfMarketsParams, |
|
|
|
GetQuotesParams, |
|
|
|
GetSearchParams |
|
|
|
} from '@ghostfolio/api/services/data-provider/interfaces/data-provider.interface'; |
|
|
|
@ -23,7 +24,9 @@ import { |
|
|
|
DividendsResponse, |
|
|
|
HistoricalResponse, |
|
|
|
LookupResponse, |
|
|
|
QuotesResponse |
|
|
|
MarketDataOfMarketsResponse, |
|
|
|
QuotesResponse, |
|
|
|
SymbolItem |
|
|
|
} from '@ghostfolio/common/interfaces'; |
|
|
|
|
|
|
|
import { Injectable, Logger } from '@nestjs/common'; |
|
|
|
@ -224,6 +227,63 @@ export class GhostfolioService implements DataProviderInterface { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public async getMarketDataOfMarkets({ |
|
|
|
includeHistoricalData = 0, |
|
|
|
requestTimeout = this.configurationService.get('REQUEST_TIMEOUT') |
|
|
|
}: GetMarketDataOfMarketsParams): Promise<MarketDataOfMarketsResponse> { |
|
|
|
let marketDataOfMarkets: MarketDataOfMarketsResponse = { |
|
|
|
fearAndGreedIndex: { |
|
|
|
CRYPTOCURRENCIES: {} as SymbolItem, |
|
|
|
STOCKS: {} as SymbolItem |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
try { |
|
|
|
const queryParams = new URLSearchParams({ |
|
|
|
includeHistoricalData: includeHistoricalData.toString() |
|
|
|
}); |
|
|
|
|
|
|
|
const response = await this.fetchService.fetch( |
|
|
|
`${this.URL}/v1/data-providers/ghostfolio/markets?${queryParams.toString()}`, |
|
|
|
{ |
|
|
|
headers: await this.getRequestHeaders(), |
|
|
|
signal: AbortSignal.timeout(requestTimeout) |
|
|
|
} |
|
|
|
); |
|
|
|
|
|
|
|
if (!response.ok) { |
|
|
|
throw new Response(await response.text(), { |
|
|
|
status: response.status, |
|
|
|
statusText: response.statusText |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
marketDataOfMarkets = |
|
|
|
(await response.json()) as MarketDataOfMarketsResponse; |
|
|
|
} catch (error) { |
|
|
|
let message = error; |
|
|
|
|
|
|
|
if (['AbortError', 'TimeoutError'].includes(error?.name)) { |
|
|
|
message = `RequestError: The operation to get the market data of markets was aborted because the request to the data provider took more than ${( |
|
|
|
requestTimeout / 1000 |
|
|
|
).toFixed(3)} seconds`;
|
|
|
|
} else if (error?.status === StatusCodes.TOO_MANY_REQUESTS) { |
|
|
|
message = 'RequestError: The daily request limit has been exceeded'; |
|
|
|
} else if ( |
|
|
|
[StatusCodes.FORBIDDEN, StatusCodes.UNAUTHORIZED].includes( |
|
|
|
error?.status |
|
|
|
) |
|
|
|
) { |
|
|
|
message = |
|
|
|
'RequestError: The API key is invalid. Please update it in the Settings section of the Admin Control panel.'; |
|
|
|
} |
|
|
|
|
|
|
|
this.logger.error(message); |
|
|
|
} |
|
|
|
|
|
|
|
return marketDataOfMarkets; |
|
|
|
} |
|
|
|
|
|
|
|
public getMaxNumberOfSymbolsPerRequest() { |
|
|
|
return 20; |
|
|
|
} |
|
|
|
|