Refresh dailyPnL on a fixed hourly interval instead of throttling

- Replace the reactive throttle with a proactive setInterval in requestSync
  that fires fetchDaysTraded exactly once per hour per client
- Remove post-fill fetchDaysTraded calls from auto-trade.ts — no longer
  needed and were causing bursts of report API requests on simultaneous fills
- Guard against duplicate intervals if requestSync fires more than once

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Senofy
2026-03-12 20:41:56 -05:00
co-authored by Claude Sonnet 4.6
parent 92b929f4ce
commit d0065ab047
2 changed files with 9 additions and 20 deletions
+9 -6
View File
@@ -34,8 +34,8 @@ export class TradovateClient {
/** True once fetchDaysTraded() has finished its last full run */
public fetchDaysComplete = false;
/** Timestamp (ms) of the last successful fetchDaysTraded run — throttled to once per hour */
private lastDaysFetch = 0;
/** NodeJS.Timeout handle for the hourly dailyPnL refresh */
private daysFetchInterval: ReturnType<typeof setInterval> | null = null;
/** Last error per account name from fetchDaysTraded() */
public lastFetchErrors: Record<string, string> = {};
/** Raw reports API response sample per account (first 100 chars) for debugging */
@@ -290,6 +290,13 @@ export class TradovateClient {
this.fetchDaysTraded();
// Refresh daily P&L once per hour — avoids hammering the reports API
if (this.daysFetchInterval) clearInterval(this.daysFetchInterval);
this.daysFetchInterval = setInterval(
() => this.fetchDaysTraded().catch((err) => console.error('[hourly fetchDaysTraded]', err)),
60 * 60 * 1_000
);
if (this.products.length > 0) {
this.syncComplete = true;
this.callbackOnSyncRequest();
@@ -315,10 +322,6 @@ export class TradovateClient {
public async fetchDaysTraded(): Promise<void> {
if (!this.accessInfo?.accessToken) return;
// Throttle to at most once per hour to avoid rate-limiting the reports API
const ONE_HOUR = 60 * 60 * 1_000;
if (Date.now() - this.lastDaysFetch < ONE_HOUR) return;
this.lastDaysFetch = Date.now();
this.fetchDaysComplete = false;
const authHeaders = { Authorization: `Bearer ${this.accessInfo.accessToken}` };