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. 35
      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;
const marketSymbolMap: {
@ -289,10 +291,10 @@ export class PortfolioCalculator {
timeWeightedInvestmentValues,
timeWeightedInvestmentValuesWithCurrencyEffect
} = this.getSymbolMetrics({
end,
end: dates?.[dates.length - 1] ?? end,
marketSymbolMap,
start,
step,
start: dates?.[0] ?? start,
step: dates.length > 1 ? differenceInDays(dates[1], dates[0]) : 1,
symbol,
exchangeRates:
exchangeRatesByCurrency[`${currencies[symbol]}${this.currency}`],

35
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({
dateRange: { start, end, step },
symbols,
@ -101,35 +108,11 @@ export class MarketDataService {
dataSources: DataSource[];
}): Promise<MarketData[]> {
return this.prismaService.$queryRaw`
WITH "lastDate" AS (
SELECT "date" FROM "MarketData"
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"
SELECT * FROM "MarketData"
WHERE "date" BETWEEN ${start} AND ${end}
AND "symbol" IN (${Prisma.join(symbols)})
AND "dataSource"::text IN (${Prisma.join(dataSources)})
WINDOW w AS (
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
${this.getDecimationFilter(step)}
ORDER BY "date"
`;
}

Loading…
Cancel
Save