From 37bd17d3c14fdc85abda987f3b18ee3ad77c51d1 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 18 Jul 2026 14:30:09 +0200 Subject: [PATCH] Task/simplify getHistorical() function response in data provider interface (#7369) * Simplify getHistorical() function response * Update changelog --- CHANGELOG.md | 6 ++++ .../ghostfolio/ghostfolio.service.ts | 4 +-- .../alpha-vantage/alpha-vantage.service.ts | 8 ++--- .../coingecko/coingecko.service.ts | 10 +++---- .../data-provider/data-provider.service.ts | 2 +- .../eod-historical-data.service.ts | 29 +++++++++---------- .../financial-modeling-prep.service.ts | 10 +++---- .../ghostfolio/ghostfolio.service.ts | 6 ++-- .../google-sheets/google-sheets.service.ts | 6 ++-- .../interfaces/data-provider.interface.ts | 4 +-- .../data-provider/manual/manual.service.ts | 17 +++++------ .../rapid-api/rapid-api.service.ts | 8 ++--- .../yahoo-finance/yahoo-finance.service.ts | 8 ++--- 13 files changed, 52 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1d8ca3b6..4e699e6cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- Simplified the `getHistorical()` function response in the data provider interface + ## 3.29.0 - 2026-07-18 ### Added diff --git a/apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.service.ts b/apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.service.ts index abbb5cbf6..2c22f0c10 100644 --- a/apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.service.ts +++ b/apps/api/src/app/endpoints/data-providers/ghostfolio/ghostfolio.service.ts @@ -171,7 +171,7 @@ export class GhostfolioService { try { const promises: Promise<{ - [symbol: string]: { [date: string]: DataProviderHistoricalResponse }; + [date: string]: DataProviderHistoricalResponse; }>[] = []; for (const dataProviderService of this.getDataProviderServices()) { @@ -185,7 +185,7 @@ export class GhostfolioService { to }) .then((historicalData) => { - result.historicalData = historicalData[symbol]; + result.historicalData = historicalData; return historicalData; }) 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 40b45a115..799f1280b 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 @@ -70,7 +70,7 @@ export class AlphaVantageService symbol, to }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: DataProviderHistoricalResponse }; + [date: string]: DataProviderHistoricalResponse; }> { try { const historicalData: { @@ -83,11 +83,9 @@ export class AlphaVantageService ); const response: { - [symbol: string]: { [date: string]: DataProviderHistoricalResponse }; + [date: string]: DataProviderHistoricalResponse; } = {}; - response[symbol] = {}; - for (const [key, timeSeries] of Object.entries( historicalData['Time Series (Digital Currency Daily)'] ).sort()) { @@ -95,7 +93,7 @@ export class AlphaVantageService isAfter(from, parse(key, DATE_FORMAT, new Date())) && isBefore(to, parse(key, DATE_FORMAT, new Date())) ) { - response[symbol][key] = { + response[key] = { marketPrice: parseFloat(timeSeries['4a. close (USD)']) }; } diff --git a/apps/api/src/services/data-provider/coingecko/coingecko.service.ts b/apps/api/src/services/data-provider/coingecko/coingecko.service.ts index 5d6ed79aa..96bc00561 100644 --- a/apps/api/src/services/data-provider/coingecko/coingecko.service.ts +++ b/apps/api/src/services/data-provider/coingecko/coingecko.service.ts @@ -115,7 +115,7 @@ export class CoinGeckoService implements DataProviderInterface, OnModuleInit { symbol, to }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: DataProviderHistoricalResponse }; + [date: string]: DataProviderHistoricalResponse; }> { try { const queryParams = new URLSearchParams({ @@ -143,13 +143,11 @@ export class CoinGeckoService implements DataProviderInterface, OnModuleInit { } const result: { - [symbol: string]: { [date: string]: DataProviderHistoricalResponse }; - } = { - [symbol]: {} - }; + [date: string]: DataProviderHistoricalResponse; + } = {}; for (const [timestamp, marketPrice] of prices) { - result[symbol][format(fromUnixTime(timestamp / 1000), DATE_FORMAT)] = { + result[format(fromUnixTime(timestamp / 1000), DATE_FORMAT)] = { marketPrice }; } 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 35dc97d2f..49f5f68f4 100644 --- a/apps/api/src/services/data-provider/data-provider.service.ts +++ b/apps/api/src/services/data-provider/data-provider.service.ts @@ -508,7 +508,7 @@ export class DataProviderService implements OnModuleInit { requestTimeout: ms('30 seconds') }) .then((data) => { - return { dataSource, symbol, data: data?.[symbol] }; + return { data, dataSource, symbol }; }) ); } 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 ebb6cd743..6bc003fc2 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 @@ -147,7 +147,7 @@ export class EodHistoricalDataService symbol, to }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: DataProviderHistoricalResponse }; + [date: string]: DataProviderHistoricalResponse; }> { symbol = this.convertToEodSymbol(symbol); @@ -166,22 +166,19 @@ export class EodHistoricalDataService }) .then((res) => res.json()); - return response.reduce( - (result, { adjusted_close, date }) => { - if (isNumber(adjusted_close)) { - result[this.convertFromEodSymbol(symbol)][date] = { - marketPrice: adjusted_close - }; - } else { - this.logger.error( - `Could not get historical market data for ${symbol} (${this.getName()}) at ${date}` - ); - } + return response.reduce((result, { adjusted_close, date }) => { + if (isNumber(adjusted_close)) { + result[date] = { + marketPrice: adjusted_close + }; + } else { + this.logger.error( + `Could not get historical market data for ${symbol} (${this.getName()}) at ${date}` + ); + } - return result; - }, - { [this.convertFromEodSymbol(symbol)]: {} } - ); + return result; + }, {}); } catch (error) { throw new Error( `Could not get historical market data for ${symbol} (${this.getName()}) from ${format( diff --git a/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts b/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts index 4e3502033..83e7fb6c2 100644 --- a/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts +++ b/apps/api/src/services/data-provider/financial-modeling-prep/financial-modeling-prep.service.ts @@ -336,14 +336,12 @@ export class FinancialModelingPrepService symbol, to }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: DataProviderHistoricalResponse }; + [date: string]: DataProviderHistoricalResponse; }> { const MAX_YEARS_PER_REQUEST = 5; const result: { - [symbol: string]: { [date: string]: DataProviderHistoricalResponse }; - } = { - [symbol]: {} - }; + [date: string]: DataProviderHistoricalResponse; + } = {}; let currentFrom = from; @@ -378,7 +376,7 @@ export class FinancialModelingPrepService isAfter(parseDate(date), currentFrom)) && isBefore(parseDate(date), currentTo) ) { - result[symbol][date] = { + result[date] = { marketPrice: close }; } diff --git a/apps/api/src/services/data-provider/ghostfolio/ghostfolio.service.ts b/apps/api/src/services/data-provider/ghostfolio/ghostfolio.service.ts index 81b997037..5b59e9a00 100644 --- a/apps/api/src/services/data-provider/ghostfolio/ghostfolio.service.ts +++ b/apps/api/src/services/data-provider/ghostfolio/ghostfolio.service.ts @@ -172,7 +172,7 @@ export class GhostfolioService implements DataProviderInterface { symbol, to }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: DataProviderHistoricalResponse }; + [date: string]: DataProviderHistoricalResponse; }> { try { const queryParams = new URLSearchParams({ @@ -198,9 +198,7 @@ export class GhostfolioService implements DataProviderInterface { const { historicalData } = (await response.json()) as HistoricalResponse; - return { - [symbol]: historicalData - }; + return historicalData; } catch (error) { if (error?.status === StatusCodes.TOO_MANY_REQUESTS) { error.name = 'RequestError'; 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 13f671bd4..75fae673e 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 @@ -60,7 +60,7 @@ export class GoogleSheetsService implements DataProviderInterface { symbol, to }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: DataProviderHistoricalResponse }; + [date: string]: DataProviderHistoricalResponse; }> { try { const sheet = await this.getSheet({ @@ -85,9 +85,7 @@ export class GoogleSheetsService implements DataProviderInterface { historicalData[format(date, DATE_FORMAT)] = { marketPrice: close }; }); - return { - [symbol]: historicalData - }; + return historicalData; } catch (error) { throw new Error( `Could not get historical market data for ${symbol} (${this.getName()}) from ${format( 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 8c2fb64d8..1e6d2496b 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 @@ -35,8 +35,8 @@ export interface DataProviderInterface { symbol, to }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: DataProviderHistoricalResponse }; - }>; // TODO: Return only one symbol + [date: string]: DataProviderHistoricalResponse; + }>; getMarketDataOfMarkets?({ includeHistoricalData, 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 66571c239..a8cfa8b0b 100644 --- a/apps/api/src/services/data-provider/manual/manual.service.ts +++ b/apps/api/src/services/data-provider/manual/manual.service.ts @@ -79,7 +79,7 @@ export class ManualService implements DataProviderInterface { symbol, to }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: DataProviderHistoricalResponse }; + [date: string]: DataProviderHistoricalResponse; }> { try { const [symbolProfile] = await this.symbolProfileService.getSymbolProfiles( @@ -90,14 +90,13 @@ export class ManualService implements DataProviderInterface { if (defaultMarketPrice) { const historical: { - [symbol: string]: { [date: string]: DataProviderHistoricalResponse }; - } = { - [symbol]: {} - }; + [date: string]: DataProviderHistoricalResponse; + } = {}; + let date = from; while (isBefore(date, to)) { - historical[symbol][format(date, DATE_FORMAT)] = { + historical[format(date, DATE_FORMAT)] = { marketPrice: defaultMarketPrice }; @@ -115,10 +114,8 @@ export class ManualService implements DataProviderInterface { }); return { - [symbol]: { - [format(getYesterday(), DATE_FORMAT)]: { - marketPrice: value - } + [format(getYesterday(), DATE_FORMAT)]: { + marketPrice: value } }; } catch (error) { 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 e704f2861..9af22b79a 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 @@ -58,7 +58,7 @@ export class RapidApiService implements DataProviderInterface { symbol, to }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: DataProviderHistoricalResponse }; + [date: string]: DataProviderHistoricalResponse; }> { try { if (symbol === ghostfolioFearAndGreedIndexSymbolStocks) { @@ -66,10 +66,8 @@ export class RapidApiService implements DataProviderInterface { if (fgi) { return { - [symbol]: { - [format(getYesterday(), DATE_FORMAT)]: { - marketPrice: fgi.previousClose.value - } + [format(getYesterday(), DATE_FORMAT)]: { + marketPrice: fgi.previousClose.value } }; } 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 93949ebc0..52fb5d5a8 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 @@ -123,7 +123,7 @@ export class YahooFinanceService implements DataProviderInterface { symbol, to }: GetHistoricalParams): Promise<{ - [symbol: string]: { [date: string]: DataProviderHistoricalResponse }; + [date: string]: DataProviderHistoricalResponse; }> { if (isSameDay(from, to)) { to = addDays(to, 1); @@ -144,13 +144,11 @@ export class YahooFinanceService implements DataProviderInterface { ); const response: { - [symbol: string]: { [date: string]: DataProviderHistoricalResponse }; + [date: string]: DataProviderHistoricalResponse; } = {}; - response[symbol] = {}; - for (const historicalItem of historicalResult) { - response[symbol][format(historicalItem.date, DATE_FORMAT)] = { + response[format(historicalItem.date, DATE_FORMAT)] = { marketPrice: historicalItem.close }; }