Browse Source

Simplify raw query

pull/3139/head
helgehatt 1 year ago
parent
commit
3f3c1292aa
  1. 8
      apps/api/src/app/portfolio/portfolio-calculator.ts
  2. 37
      apps/api/src/services/market-data/market-data.service.ts

8
apps/api/src/app/portfolio/portfolio-calculator.ts

@ -223,6 +223,8 @@ export class PortfolioCalculator {
} }
}); });
const dates = uniq(marketSymbols.map((x) => x.date));
this.dataProviderInfos = dataProviderInfos; this.dataProviderInfos = dataProviderInfos;
const marketSymbolMap: { const marketSymbolMap: {
@ -289,10 +291,10 @@ export class PortfolioCalculator {
timeWeightedInvestmentValues, timeWeightedInvestmentValues,
timeWeightedInvestmentValuesWithCurrencyEffect timeWeightedInvestmentValuesWithCurrencyEffect
} = this.getSymbolMetrics({ } = this.getSymbolMetrics({
end, end: dates?.[dates.length - 1] ?? end,
marketSymbolMap, marketSymbolMap,
start, start: dates?.[0] ?? start,
step, step: dates.length > 1 ? differenceInDays(dates[1], dates[0]) : 1,
symbol, symbol,
exchangeRates: exchangeRates:
exchangeRatesByCurrency[`${currencies[symbol]}${this.currency}`], exchangeRatesByCurrency[`${currencies[symbol]}${this.currency}`],

37
apps/api/src/services/market-data/market-data.service.ts

@ -91,6 +91,13 @@ export class MarketDataService {
}); });
} }
private getDecimationFilter(step: number): Prisma.Sql {
if (step > 200) return Prisma.sql`AND EXTRACT(DOY FROM "date") = 1`;
if (step > 20) return Prisma.sql`AND EXTRACT(DAY FROM "date") = 1`;
if (step > 2) return Prisma.sql`AND EXTRACT(DOW FROM "date") = 1`;
return Prisma.empty;
}
public async getDecimatedRange({ public async getDecimatedRange({
dateRange: { start, end, step }, dateRange: { start, end, step },
symbols, symbols,
@ -101,35 +108,11 @@ export class MarketDataService {
dataSources: DataSource[]; dataSources: DataSource[];
}): Promise<MarketData[]> { }): Promise<MarketData[]> {
return this.prismaService.$queryRaw` return this.prismaService.$queryRaw`
WITH "lastDate" AS ( SELECT * FROM "MarketData"
SELECT "date" FROM "MarketData" WHERE "date" BETWEEN ${start} AND ${end}
WHERE "date" BETWEEN ${start} AND ${end}
ORDER BY "date" DESC LIMIT 1
), "lastRows" AS (
SELECT * FROM "MarketData"
WHERE "date" = (SELECT "date" FROM "lastDate")
AND "symbol" IN (${Prisma.join(symbols)})
AND "dataSource"::text IN (${Prisma.join(dataSources)})
)
SELECT DISTINCT
FIRST_VALUE("createdAt") OVER w AS "createdAt",
FIRST_VALUE("dataSource") OVER w AS "dataSource",
FIRST_VALUE("date") OVER w AS "date",
FIRST_VALUE("id") OVER w AS "id",
FIRST_VALUE("marketPrice") OVER w AS "marketPrice",
FIRST_VALUE("state") OVER w AS "state",
FIRST_VALUE("symbol") OVER w AS "symbol"
FROM "MarketData"
WHERE "date" BETWEEN ${start} AND ${end}
AND "symbol" IN (${Prisma.join(symbols)}) AND "symbol" IN (${Prisma.join(symbols)})
AND "dataSource"::text IN (${Prisma.join(dataSources)}) AND "dataSource"::text IN (${Prisma.join(dataSources)})
WINDOW w AS ( ${this.getDecimationFilter(step)}
PARTITION BY "symbol", FLOOR(
(EXTRACT(EPOCH FROM "date") - EXTRACT(EPOCH FROM ${start})) -- Subtract {start} to make it first value
/ (60 * 60 * 24 * ${step}) -- Divide by {step} number of days
) ORDER BY "date" -- Round down to make every {step} values equal
)
UNION SELECT * FROM "lastRows" -- Add rows with the end date
ORDER BY "date" ORDER BY "date"
`; `;
} }

Loading…
Cancel
Save