From 00808b26187a4f4668670ef72aa02335fe34e93b Mon Sep 17 00:00:00 2001 From: Vincent Chau <99756290+vincentwschau@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:34:58 -0500 Subject: [PATCH 1/3] [TRA-890] Return nearest hour PnL as final data point for vaults pnl. --- .../api/v4/vault-controller.test.ts | 21 +++++----- .../controllers/api/v4/vault-controller.ts | 38 ++++++++++++++++++- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/indexer/services/comlink/__tests__/controllers/api/v4/vault-controller.test.ts b/indexer/services/comlink/__tests__/controllers/api/v4/vault-controller.test.ts index 5d8a1ef709..6b5703beac 100644 --- a/indexer/services/comlink/__tests__/controllers/api/v4/vault-controller.test.ts +++ b/indexer/services/comlink/__tests__/controllers/api/v4/vault-controller.test.ts @@ -298,13 +298,14 @@ describe('vault-controller#V4', () => { }); it.each([ - ['no resolution', '', [1, 2]], - ['daily resolution', '?resolution=day', [1, 2]], - ['hourly resolution', '?resolution=hour', [1, 2, 3, 4]], + ['no resolution', '', [1, 2], 4], + ['daily resolution', '?resolution=day', [1, 2], 4], + ['hourly resolution', '?resolution=hour', [1, 2, 3, 4], 4], ])('Get /vaults/historicalPnl with single vault subaccount (%s)', async ( _name: string, queryParam: string, expectedTicksIndex: number[], + currentTickIndex: number, ) => { await VaultTable.create({ ...testConstants.defaultVault, @@ -313,7 +314,7 @@ describe('vault-controller#V4', () => { }); const createdPnlTicks: PnlTicksFromDatabase[] = await createPnlTicks(); const finalTick: PnlTicksFromDatabase = { - ...createdPnlTicks[expectedTicksIndex[expectedTicksIndex.length - 1]], + ...createdPnlTicks[currentTickIndex], equity: Big(vault1Equity).toFixed(), blockHeight: latestBlockHeight, blockTime: latestTime.toISO(), @@ -338,14 +339,16 @@ describe('vault-controller#V4', () => { }); it.each([ - ['no resolution', '', [1, 2], [6, 7]], - ['daily resolution', '?resolution=day', [1, 2], [6, 7]], - ['hourly resolution', '?resolution=hour', [1, 2, 3, 4], [6, 7, 8, 9]], + ['no resolution', '', [1, 2], [6, 7], 4, 9], + ['daily resolution', '?resolution=day', [1, 2], [6, 7], 4, 9], + ['hourly resolution', '?resolution=hour', [1, 2, 3, 4], [6, 7, 8, 9], 4, 9], ])('Get /vaults/historicalPnl with 2 vault subaccounts (%s)', async ( _name: string, queryParam: string, expectedTicksIndex1: number[], expectedTicksIndex2: number[], + curerntTickIndex1: number, + currentTickIndex2: number, ) => { await Promise.all([ VaultTable.create({ @@ -361,14 +364,14 @@ describe('vault-controller#V4', () => { ]); const createdPnlTicks: PnlTicksFromDatabase[] = await createPnlTicks(); const finalTick1: PnlTicksFromDatabase = { - ...createdPnlTicks[expectedTicksIndex1[expectedTicksIndex1.length - 1]], + ...createdPnlTicks[curerntTickIndex1], equity: Big(vault1Equity).toFixed(), blockHeight: latestBlockHeight, blockTime: latestTime.toISO(), createdAt: latestTime.toISO(), }; const finalTick2: PnlTicksFromDatabase = { - ...createdPnlTicks[expectedTicksIndex2[expectedTicksIndex2.length - 1]], + ...createdPnlTicks[currentTickIndex2], equity: Big(vault2Equity).toFixed(), blockHeight: latestBlockHeight, blockTime: latestTime.toISO(), diff --git a/indexer/services/comlink/src/controllers/api/v4/vault-controller.ts b/indexer/services/comlink/src/controllers/api/v4/vault-controller.ts index b4e75197e7..19c846eff6 100644 --- a/indexer/services/comlink/src/controllers/api/v4/vault-controller.ts +++ b/indexer/services/comlink/src/controllers/api/v4/vault-controller.ts @@ -35,7 +35,7 @@ import Big from 'big.js'; import bounds from 'binary-searching'; import express from 'express'; import { checkSchema, matchedData } from 'express-validator'; -import _ from 'lodash'; +import _, { Dictionary } from 'lodash'; import { DateTime } from 'luxon'; import { Controller, Get, Query, Route, @@ -152,15 +152,22 @@ class VaultController extends Controller { vaultPnlTicks, vaultPositions, latestBlock, + latestTicks, ] : [ PnlTicksFromDatabase[], Map, BlockFromDatabase, + PnlTicksFromDatabase[], ] = await Promise.all([ getVaultSubaccountPnlTicks(_.keys(vaultSubaccounts), getResolution(resolution)), getVaultPositions(vaultSubaccounts), BlockTable.getLatest(), + getLatestPnlTicks(_.keys(vaultSubaccounts)), ]); + const latestTicksBySubaccountId: Dictionary = _.keyBy( + latestTicks, + 'subaccountId', + ); const groupedVaultPnlTicks: VaultHistoricalPnl[] = _(vaultPnlTicks) .filter((pnlTickFromDatabsae: PnlTicksFromDatabase): boolean => { @@ -185,6 +192,7 @@ class VaultController extends Controller { currentEquity, pnlTicks, latestBlock, + latestTicksBySubaccountId[subaccountId], ); return { @@ -551,6 +559,34 @@ function getPnlTicksWithCurrentTick( return pnlTicks.concat([currentTick]); } +export async function getLatestPnlTicks( + vaultSubaccountIds: string[], +): Promise { + const [ + latestPnlTicks, + adjustByPnlTicks, + ] : [ + PnlTicksFromDatabase[], + PnlTicksFromDatabase[], + ] = await Promise.all([ + PnlTicksTable.getLatestPnlTick( + vaultSubaccountIds, + DateTime.utc(), + ), + PnlTicksTable.getLatestPnlTick( + vaultSubaccountIds, + // Add a buffer of 10 minutes to get the first PnL tick for PnL data as PnL ticks aren't + // created exactly on the hour. + getVautlPnlStartDate().plus({ minutes: 10 }), + ), + ]); + const adjustedPnlTicks: PnlTicksFromDatabase[] = adjustVaultPnlTicks( + latestPnlTicks, + adjustByPnlTicks, + ); + return adjustedPnlTicks; +} + export async function getLatestPnlTick( vaultSubaccountIds: string[], vaults: VaultFromDatabase[], From 014315ca787b9ca726af69a127e883a2af697f1b Mon Sep 17 00:00:00 2001 From: Vincent Chau <99756290+vincentwschau@users.noreply.github.com> Date: Tue, 26 Nov 2024 15:51:25 -0500 Subject: [PATCH 2/3] Fix typos. --- .../controllers/api/v4/vault-controller.test.ts | 4 ++-- .../src/controllers/api/v4/vault-controller.ts | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/indexer/services/comlink/__tests__/controllers/api/v4/vault-controller.test.ts b/indexer/services/comlink/__tests__/controllers/api/v4/vault-controller.test.ts index 6b5703beac..8cf06ddcab 100644 --- a/indexer/services/comlink/__tests__/controllers/api/v4/vault-controller.test.ts +++ b/indexer/services/comlink/__tests__/controllers/api/v4/vault-controller.test.ts @@ -347,7 +347,7 @@ describe('vault-controller#V4', () => { queryParam: string, expectedTicksIndex1: number[], expectedTicksIndex2: number[], - curerntTickIndex1: number, + currentTickIndex1: number, currentTickIndex2: number, ) => { await Promise.all([ @@ -364,7 +364,7 @@ describe('vault-controller#V4', () => { ]); const createdPnlTicks: PnlTicksFromDatabase[] = await createPnlTicks(); const finalTick1: PnlTicksFromDatabase = { - ...createdPnlTicks[curerntTickIndex1], + ...createdPnlTicks[currentTickIndex1], equity: Big(vault1Equity).toFixed(), blockHeight: latestBlockHeight, blockTime: latestTime.toISO(), diff --git a/indexer/services/comlink/src/controllers/api/v4/vault-controller.ts b/indexer/services/comlink/src/controllers/api/v4/vault-controller.ts index 19c846eff6..80143dadb7 100644 --- a/indexer/services/comlink/src/controllers/api/v4/vault-controller.ts +++ b/indexer/services/comlink/src/controllers/api/v4/vault-controller.ts @@ -358,13 +358,13 @@ async function getVaultSubaccountPnlTicks( VaultPnlTicksView.getVaultsPnl( resolution, windowSeconds, - getVautlPnlStartDate(), + getVaultPnlStartDate(), ), PnlTicksTable.getLatestPnlTick( vaultSubaccountIds, // Add a buffer of 10 minutes to get the first PnL tick for PnL data as PnL ticks aren't // created exactly on the hour. - getVautlPnlStartDate().plus({ minutes: 10 }), + getVaultPnlStartDate().plus({ minutes: 10 }), ), ]); @@ -577,7 +577,7 @@ export async function getLatestPnlTicks( vaultSubaccountIds, // Add a buffer of 10 minutes to get the first PnL tick for PnL data as PnL ticks aren't // created exactly on the hour. - getVautlPnlStartDate().plus({ minutes: 10 }), + getVaultPnlStartDate().plus({ minutes: 10 }), ), ]); const adjustedPnlTicks: PnlTicksFromDatabase[] = adjustVaultPnlTicks( @@ -601,13 +601,13 @@ export async function getLatestPnlTick( VaultPnlTicksView.getVaultsPnl( PnlTickInterval.hour, config.VAULT_LATEST_PNL_TICK_WINDOW_HOURS * 60 * 60, - getVautlPnlStartDate(), + getVaultPnlStartDate(), ), PnlTicksTable.getLatestPnlTick( vaultSubaccountIds, // Add a buffer of 10 minutes to get the first PnL tick for PnL data as PnL ticks aren't // created exactly on the hour. - getVautlPnlStartDate().plus({ minutes: 10 }), + getVaultPnlStartDate().plus({ minutes: 10 }), ), ]); const adjustedPnlTicks: PnlTicksFromDatabase[] = adjustVaultPnlTicks( @@ -834,7 +834,7 @@ async function getVaultMapping(): Promise { return validVaultMapping; } -function getVautlPnlStartDate(): DateTime { +function getVaultPnlStartDate(): DateTime { const startDate: DateTime = DateTime.fromISO(config.VAULT_PNL_START_DATE).toUTC(); return startDate; } From 8ff8d07db99362907681a9918b983ce2e5ee877f Mon Sep 17 00:00:00 2001 From: Vincent Chau <99756290+vincentwschau@users.noreply.github.com> Date: Tue, 26 Nov 2024 16:52:39 -0500 Subject: [PATCH 3/3] Fix tests. --- .../__tests__/controllers/api/v4/vault-controller.test.ts | 4 +++- .../comlink/src/controllers/api/v4/vault-controller.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/indexer/services/comlink/__tests__/controllers/api/v4/vault-controller.test.ts b/indexer/services/comlink/__tests__/controllers/api/v4/vault-controller.test.ts index 8cf06ddcab..4035552057 100644 --- a/indexer/services/comlink/__tests__/controllers/api/v4/vault-controller.test.ts +++ b/indexer/services/comlink/__tests__/controllers/api/v4/vault-controller.test.ts @@ -21,7 +21,7 @@ import { import { RequestMethod, VaultHistoricalPnl } from '../../../../src/types'; import request from 'supertest'; import { getFixedRepresentation, sendRequest } from '../../../helpers/helpers'; -import { DateTime } from 'luxon'; +import { DateTime, Settings } from 'luxon'; import Big from 'big.js'; import config from '../../../../src/config'; @@ -124,6 +124,7 @@ describe('vault-controller#V4', () => { effectiveAtHeight: twoDayBlockHeight, }), ]); + Settings.now = () => latestTime.valueOf(); }); afterEach(async () => { @@ -133,6 +134,7 @@ describe('vault-controller#V4', () => { config.VAULT_PNL_HISTORY_HOURS = vaultPnlHistoryHoursPrev; config.VAULT_LATEST_PNL_TICK_WINDOW_HOURS = vaultPnlLastPnlWindowPrev; config.VAULT_PNL_START_DATE = vaultPnlStartDatePrev; + Settings.now = () => new Date().valueOf(); }); it.each([ diff --git a/indexer/services/comlink/src/controllers/api/v4/vault-controller.ts b/indexer/services/comlink/src/controllers/api/v4/vault-controller.ts index 80143dadb7..4df7f35fe4 100644 --- a/indexer/services/comlink/src/controllers/api/v4/vault-controller.ts +++ b/indexer/services/comlink/src/controllers/api/v4/vault-controller.ts @@ -571,7 +571,7 @@ export async function getLatestPnlTicks( ] = await Promise.all([ PnlTicksTable.getLatestPnlTick( vaultSubaccountIds, - DateTime.utc(), + DateTime.now().toUTC(), ), PnlTicksTable.getLatestPnlTick( vaultSubaccountIds,