From c88ff79d0bb215db131023035323528a31d19971 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 11 Oct 2026 09:37:43 +0200 Subject: [PATCH] Task/refactor historical market data query (#8116) Refactor historical market data query --- .../src/app/portfolio/portfolio.service.ts | 10 ++--- .../data-provider/data-provider.service.ts | 42 +++++++++---------- .../exchange-rate-data.service.ts | 10 ++--- 3 files changed, 30 insertions(+), 32 deletions(-) diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 343da076fa..c67bb51064 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -1056,11 +1056,11 @@ export class PortfolioService { ); }); - const historicalData = await this.dataProviderService.getHistorical( - [{ dataSource, symbol }], - parseISO(dateOfFirstActivity, { in: utc }), - new Date() - ); + const historicalData = await this.dataProviderService.getHistorical({ + assetProfileIdentifiers: [{ dataSource, symbol }], + from: parseISO(dateOfFirstActivity, { in: utc }), + to: new Date() + }); const [firstActivity] = activitiesOfHolding; const referenceUnitPrice = 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 cf281f5f52..e5a4f6c845 100644 --- a/apps/api/src/services/data-provider/data-provider.service.ts +++ b/apps/api/src/services/data-provider/data-provider.service.ts @@ -369,11 +369,15 @@ export class DataProviderService implements OnModuleInit { }); } - public async getHistorical( - aItems: AssetProfileIdentifier[], - from: Date, - to: Date - ): Promise<{ + public async getHistorical({ + assetProfileIdentifiers, + from, + to + }: { + assetProfileIdentifiers: AssetProfileIdentifier[]; + from: Date; + to: Date; + }): Promise<{ [assetProfileIdentifier: string]: { [date: string]: DataProviderHistoricalResponse; }; @@ -384,35 +388,29 @@ export class DataProviderService implements OnModuleInit { }; } = {}; - if (isEmpty(aItems) || !isValid(from) || !isValid(to)) { + if (isEmpty(assetProfileIdentifiers) || !isValid(from) || !isValid(to)) { return response; } - const rangeQuery = - from && to - ? Prisma.sql`AND date >= ${format(from, DATE_FORMAT, { - in: utc - })}::timestamp AND date <= ${format(to, DATE_FORMAT, { - in: utc - })}::timestamp` - : Prisma.empty; - - const assetProfileIdentifiers = aItems.map(({ dataSource, symbol }) => { - return Prisma.sql`(${dataSource}::"DataSource", ${symbol})`; - }); + const assetProfileIdentifierTuples = assetProfileIdentifiers.map( + ({ dataSource, symbol }) => { + return Prisma.sql`(${dataSource}::"DataSource", ${symbol})`; + } + ); try { - const marketDataByGranularity: Pick< + const marketDataItems: Pick< MarketData, 'dataSource' | 'date' | 'marketPrice' | 'symbol' >[] = await this.prismaService.$queryRaw` SELECT "dataSource", "date", "marketPrice", "symbol" FROM "MarketData" - WHERE ("dataSource", "symbol") IN (${Prisma.join(assetProfileIdentifiers)}) - ${rangeQuery} + WHERE ("dataSource", "symbol") IN (${Prisma.join(assetProfileIdentifierTuples)}) + AND date >= ${format(from, DATE_FORMAT, { in: utc })}::timestamp + AND date <= ${format(to, DATE_FORMAT, { in: utc })}::timestamp ORDER BY date;`; - response = marketDataByGranularity.reduce((r, marketData) => { + response = marketDataItems.reduce((r, marketData) => { const { dataSource, date, marketPrice, symbol } = marketData; const assetProfileIdentifier = getAssetProfileIdentifier({ diff --git a/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts b/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts index 59795cad6a..b68ed2fb15 100644 --- a/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts +++ b/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts @@ -173,11 +173,11 @@ export class ExchangeRateDataService { { in: utc } ); - const historicalData = await this.dataProviderService.getHistorical( - this.currencyPairs, - startOfUtcDateOfYesterday, - startOfUtcDateOfYesterday - ); + const historicalData = await this.dataProviderService.getHistorical({ + assetProfileIdentifiers: this.currencyPairs, + from: startOfUtcDateOfYesterday, + to: startOfUtcDateOfYesterday + }); const quotes = await this.dataProviderService.getQuotes({ items: this.currencyPairs.map(({ dataSource, symbol }) => {