diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c2b2f842..ef9c5337d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Extended the date range support by week to date (`WTD`) and month to date (`MTD`) in the assistant (experimental) +- Added support for importing dividends from _EOD Historical Data_ - Added `healthcheck` for the _Ghostfolio_ service to the `docker-compose` files (`docker-compose.yml` and `docker-compose.build.yml`) ### Changed diff --git a/apps/api/src/services/data-provider/data-provider.service.ts b/apps/api/src/services/data-provider/data-provider.service.ts index b8ea11f25..57d970fd6 100644 --- a/apps/api/src/services/data-provider/data-provider.service.ts +++ b/apps/api/src/services/data-provider/data-provider.service.ts @@ -134,7 +134,8 @@ export class DataProviderService { from, granularity, symbol, - to + to, + requestTimeout: ms('30 seconds') }); } diff --git a/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts b/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts index 37f6ee9ea..38b2e8a42 100644 --- a/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts +++ b/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts @@ -20,7 +20,7 @@ import { DataSource, SymbolProfile } from '@prisma/client'; -import { format, isToday } from 'date-fns'; +import { addDays, format, isSameDay, isToday } from 'date-fns'; import got from 'got'; @Injectable() @@ -54,8 +54,62 @@ export class EodHistoricalDataService implements DataProviderInterface { }; } - public async getDividends({}: GetDividendsParams) { - return {}; + public async getDividends({ + from, + requestTimeout = this.configurationService.get('REQUEST_TIMEOUT'), + symbol, + to + }: GetDividendsParams): Promise<{ + [date: string]: IDataProviderHistoricalResponse; + }> { + symbol = this.convertToEodSymbol(symbol); + + if (isSameDay(from, to)) { + to = addDays(to, 1); + } + + try { + const abortController = new AbortController(); + + const response: { + [date: string]: IDataProviderHistoricalResponse; + } = {}; + + setTimeout(() => { + abortController.abort(); + }, requestTimeout); + + const historicalResult = await got( + `${this.URL}/div/${symbol}?api_token=${ + this.apiKey + }&fmt=json&from=${format(from, DATE_FORMAT)}&to=${format( + to, + DATE_FORMAT + )}`, + { + // @ts-ignore + signal: abortController.signal + } + ).json(); + + for (const { date, value } of historicalResult) { + response[date] = { + marketPrice: value + }; + } + + return response; + } catch (error) { + Logger.error( + `Could not get dividends for ${symbol} (${this.getName()}) from ${format( + from, + DATE_FORMAT + )} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}`, + 'EodHistoricalDataService' + ); + + return {}; + } } public async getHistorical({ diff --git a/apps/api/src/services/data-provider/interfaces/data-provider.interface.ts b/apps/api/src/services/data-provider/interfaces/data-provider.interface.ts index 72365f990..044836d82 100644 --- a/apps/api/src/services/data-provider/interfaces/data-provider.interface.ts +++ b/apps/api/src/services/data-provider/interfaces/data-provider.interface.ts @@ -45,6 +45,7 @@ export interface DataProviderInterface { export interface GetDividendsParams { from: Date; granularity?: Granularity; + requestTimeout?: number; symbol: string; to: Date; }