From fc5a56309d2b8d9c1a9fb3db574eba3d5ee5c451 Mon Sep 17 00:00:00 2001 From: Thomas <4159106+dtslvr@users.noreply.github.com> Date: Sat, 7 Jan 2023 10:09:56 +0100 Subject: [PATCH] Refactoring --- apps/api/src/app/symbol/symbol.service.ts | 18 ++- .../alpha-vantage/alpha-vantage.service.ts | 14 +++ .../data-provider/data-provider.service.ts | 21 ++++ .../eod-historical-data.service.ts | 14 +++ .../ghostfolio-scraper-api.service.ts | 14 +++ .../google-sheets/google-sheets.service.ts | 14 +++ .../interfaces/data-provider.interface.ts | 12 ++ .../data-provider/manual/manual.service.ts | 14 +++ .../rapid-api/rapid-api.service.ts | 14 +++ .../yahoo-finance/yahoo-finance.service.ts | 108 +++++++++--------- .../activities-table.component.html | 2 +- 11 files changed, 178 insertions(+), 67 deletions(-) diff --git a/apps/api/src/app/symbol/symbol.service.ts b/apps/api/src/app/symbol/symbol.service.ts index cb29b2c2b..9b5311c8d 100644 --- a/apps/api/src/app/symbol/symbol.service.ts +++ b/apps/api/src/app/symbol/symbol.service.ts @@ -1,5 +1,4 @@ import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; -import { YahooFinanceService } from '@ghostfolio/api/services/data-provider/yahoo-finance/yahoo-finance.service'; import { IDataGatheringItem, IDataProviderHistoricalResponse @@ -23,8 +22,7 @@ export class SymbolService { public constructor( private readonly dataProviderService: DataProviderService, private readonly marketDataService: MarketDataService, - private readonly symbolProfileService: SymbolProfileService, - private readonly yahooFinanceService: YahooFinanceService + private readonly symbolProfileService: SymbolProfileService ) {} public async get({ @@ -84,17 +82,17 @@ export class SymbolService { symbol } ]), - // TODO: Use DataProviderService - this.yahooFinanceService.getDividends( + await this.dataProviderService.getDividends({ + dataSource, symbol, - 'day', - subYears(date, 5), - date - ) + from: subYears(date, 5), + granularity: 'day', + to: date + }) ]); return { - activities: Object.entries(historicalData[symbol]).map( + activities: Object.entries(historicalData).map( ([dateString, historicalDataItem]) => { return { accountId: undefined, diff --git a/apps/api/src/services/data-provider/alpha-vantage/alpha-vantage.service.ts b/apps/api/src/services/data-provider/alpha-vantage/alpha-vantage.service.ts index 41bd715b1..481bd0ccc 100644 --- a/apps/api/src/services/data-provider/alpha-vantage/alpha-vantage.service.ts +++ b/apps/api/src/services/data-provider/alpha-vantage/alpha-vantage.service.ts @@ -37,6 +37,20 @@ export class AlphaVantageService implements DataProviderInterface { }; } + public async getDividends({ + from, + granularity = 'day', + symbol, + to + }: { + from: Date; + granularity: Granularity; + symbol: string; + to: Date; + }) { + return {}; + } + public async getHistorical( aSymbol: string, aGranularity: Granularity = 'day', 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 7092e1112..0173dc82e 100644 --- a/apps/api/src/services/data-provider/data-provider.service.ts +++ b/apps/api/src/services/data-provider/data-provider.service.ts @@ -23,6 +23,27 @@ export class DataProviderService { private readonly prismaService: PrismaService ) {} + public async getDividends({ + dataSource, + from, + granularity = 'day', + symbol, + to + }: { + dataSource: DataSource; + from: Date; + granularity: Granularity; + symbol: string; + to: Date; + }) { + return this.getDataProvider(DataSource[dataSource]).getDividends({ + from, + granularity, + symbol, + to + }); + } + public async getHistorical( aItems: IDataGatheringItem[], aGranularity: Granularity = 'month', 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 c87c6ec3e..cbfd67e2e 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 @@ -37,6 +37,20 @@ export class EodHistoricalDataService implements DataProviderInterface { }; } + public async getDividends({ + from, + granularity = 'day', + symbol, + to + }: { + from: Date; + granularity: Granularity; + symbol: string; + to: Date; + }) { + return {}; + } + public async getHistorical( aSymbol: string, aGranularity: Granularity = 'day', diff --git a/apps/api/src/services/data-provider/ghostfolio-scraper-api/ghostfolio-scraper-api.service.ts b/apps/api/src/services/data-provider/ghostfolio-scraper-api/ghostfolio-scraper-api.service.ts index 8da34410f..7412fec7b 100644 --- a/apps/api/src/services/data-provider/ghostfolio-scraper-api/ghostfolio-scraper-api.service.ts +++ b/apps/api/src/services/data-provider/ghostfolio-scraper-api/ghostfolio-scraper-api.service.ts @@ -37,6 +37,20 @@ export class GhostfolioScraperApiService implements DataProviderInterface { }; } + public async getDividends({ + from, + granularity = 'day', + symbol, + to + }: { + from: Date; + granularity: Granularity; + symbol: string; + to: Date; + }) { + return {}; + } + public async getHistorical( aSymbol: string, aGranularity: Granularity = 'day', diff --git a/apps/api/src/services/data-provider/google-sheets/google-sheets.service.ts b/apps/api/src/services/data-provider/google-sheets/google-sheets.service.ts index cc6af5241..201d57aa4 100644 --- a/apps/api/src/services/data-provider/google-sheets/google-sheets.service.ts +++ b/apps/api/src/services/data-provider/google-sheets/google-sheets.service.ts @@ -34,6 +34,20 @@ export class GoogleSheetsService implements DataProviderInterface { }; } + public async getDividends({ + from, + granularity = 'day', + symbol, + to + }: { + from: Date; + granularity: Granularity; + symbol: string; + to: Date; + }) { + return {}; + } + public async getHistorical( aSymbol: string, aGranularity: Granularity = 'day', 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 6719f3099..c51adb985 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 @@ -11,6 +11,18 @@ export interface DataProviderInterface { getAssetProfile(aSymbol: string): Promise>; + getDividends({ + from, + granularity, + symbol, + to + }: { + from: Date; + granularity: Granularity; + symbol: string; + to: Date; + }): Promise<{ [date: string]: IDataProviderHistoricalResponse }>; + getHistorical( aSymbol: string, aGranularity: Granularity, diff --git a/apps/api/src/services/data-provider/manual/manual.service.ts b/apps/api/src/services/data-provider/manual/manual.service.ts index a364276ef..7b6051087 100644 --- a/apps/api/src/services/data-provider/manual/manual.service.ts +++ b/apps/api/src/services/data-provider/manual/manual.service.ts @@ -29,6 +29,20 @@ export class ManualService implements DataProviderInterface { }; } + public async getDividends({ + from, + granularity = 'day', + symbol, + to + }: { + from: Date; + granularity: Granularity; + symbol: string; + to: Date; + }) { + return {}; + } + public async getHistorical( aSymbol: string, aGranularity: Granularity = 'day', diff --git a/apps/api/src/services/data-provider/rapid-api/rapid-api.service.ts b/apps/api/src/services/data-provider/rapid-api/rapid-api.service.ts index 1bf057745..f5119e0b7 100644 --- a/apps/api/src/services/data-provider/rapid-api/rapid-api.service.ts +++ b/apps/api/src/services/data-provider/rapid-api/rapid-api.service.ts @@ -31,6 +31,20 @@ export class RapidApiService implements DataProviderInterface { }; } + public async getDividends({ + from, + granularity = 'day', + symbol, + to + }: { + from: Date; + granularity: Granularity; + symbol: string; + to: Date; + }) { + return {}; + } + public async getHistorical( aSymbol: string, aGranularity: Granularity = 'day', diff --git a/apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts b/apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts index 2fcb3e62c..e77d90f42 100644 --- a/apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts +++ b/apps/api/src/services/data-provider/yahoo-finance/yahoo-finance.service.ts @@ -160,70 +160,58 @@ export class YahooFinanceService implements DataProviderInterface { return response; } - public async getDividends( - aSymbol: string, - aGranularity: Granularity = 'day', - from: Date, - to: Date - ): Promise<{ - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; - }> { - // TODO: Call getHistorical() - + public async getDividends({ + from, + granularity = 'day', + symbol, + to + }: { + from: Date; + granularity: Granularity; + symbol: string; + to: Date; + }) { if (isSameDay(from, to)) { to = addDays(to, 1); } - const yahooFinanceSymbol = this.convertToYahooFinanceSymbol(aSymbol); + const yahooFinanceSymbol = this.convertToYahooFinanceSymbol(symbol); try { const historicalResult = await yahooFinance.historical( yahooFinanceSymbol, { events: 'dividends', - interval: '1d', + interval: granularity === 'month' ? '1mo' : '1d', period1: format(from, DATE_FORMAT), period2: format(to, DATE_FORMAT) } ); const response: { - [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; + [date: string]: IDataProviderHistoricalResponse; } = {}; - // Convert symbol back - const symbol = this.convertFromYahooFinanceSymbol(yahooFinanceSymbol); - - response[symbol] = {}; - for (const historicalItem of historicalResult) { - let marketPrice = historicalItem.dividends; - - if (symbol === `${this.baseCurrency}GBp`) { - // Convert GPB to GBp (pence) - marketPrice = new Big(marketPrice).mul(100).toNumber(); - } else if (symbol === `${this.baseCurrency}ILA`) { - // Convert ILS to ILA - marketPrice = new Big(marketPrice).mul(100).toNumber(); - } else if (symbol === `${this.baseCurrency}ZAc`) { - // Convert ZAR to ZAc (cents) - marketPrice = new Big(marketPrice).mul(100).toNumber(); - } - - response[symbol][format(historicalItem.date, DATE_FORMAT)] = { - marketPrice + response[format(historicalItem.date, DATE_FORMAT)] = { + marketPrice: this.getConvertedValue({ + symbol, + value: historicalItem.dividends + }) }; } return response; } catch (error) { - // TODO: Log error and return empty response - throw new Error( - `Could not get historical market data for ${aSymbol} (${this.getName()}) from ${format( + Logger.error( + `Could not get dividends for ${symbol} (${this.getName()}) from ${format( from, DATE_FORMAT - )} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}` + )} to ${format(to, DATE_FORMAT)}: [${error.name}] ${error.message}`, + 'YahooFinanceService' ); + + return {}; } } @@ -255,27 +243,14 @@ export class YahooFinanceService implements DataProviderInterface { [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; } = {}; - // Convert symbol back - const symbol = this.convertFromYahooFinanceSymbol(yahooFinanceSymbol); - - response[symbol] = {}; + response[aSymbol] = {}; for (const historicalItem of historicalResult) { - let marketPrice = historicalItem.close; - - if (symbol === `${this.baseCurrency}GBp`) { - // Convert GPB to GBp (pence) - marketPrice = new Big(marketPrice).mul(100).toNumber(); - } else if (symbol === `${this.baseCurrency}ILA`) { - // Convert ILS to ILA - marketPrice = new Big(marketPrice).mul(100).toNumber(); - } else if (symbol === `${this.baseCurrency}ZAc`) { - // Convert ZAR to ZAc (cents) - marketPrice = new Big(marketPrice).mul(100).toNumber(); - } - - response[symbol][format(historicalItem.date, DATE_FORMAT)] = { - marketPrice, + response[aSymbol][format(historicalItem.date, DATE_FORMAT)] = { + marketPrice: this.getConvertedValue({ + symbol: aSymbol, + value: historicalItem.close + }), performance: historicalItem.open - historicalItem.close }; } @@ -490,6 +465,27 @@ export class YahooFinanceService implements DataProviderInterface { return name || shortName || symbol; } + private getConvertedValue({ + symbol, + value + }: { + symbol: string; + value: number; + }) { + if (symbol === `${this.baseCurrency}GBp`) { + // Convert GPB to GBp (pence) + return new Big(value).mul(100).toNumber(); + } else if (symbol === `${this.baseCurrency}ILA`) { + // Convert ILS to ILA + return new Big(value).mul(100).toNumber(); + } else if (symbol === `${this.baseCurrency}ZAc`) { + // Convert ZAR to ZAc (cents) + return new Big(value).mul(100).toNumber(); + } + + return value; + } + private parseAssetClass(aPrice: Price): { assetClass: AssetClass; assetSubClass: AssetSubClass; diff --git a/libs/ui/src/lib/activities-table/activities-table.component.html b/libs/ui/src/lib/activities-table/activities-table.component.html index 48ad349e7..b841b4d77 100644 --- a/libs/ui/src/lib/activities-table/activities-table.component.html +++ b/libs/ui/src/lib/activities-table/activities-table.component.html @@ -393,7 +393,7 @@ mat-menu-item (click)="onImportDividends()" > - + Import Dividends