Session rest: a rest across the 5 PM roll reports unsynced; health excuses a wake
A firm resting across the trade-date roll kept reporting its last snapshot, so yesterday's realized P&L and DLL lockouts counted as accounts already traded today (Nik's Topstep read 5/5 traded at 5:31 PM from 3:29 PM data). Its report is now the unsynced one until it logs back in; a rest within one trade date reports as before. /api/health also counts a firm logging back in after a rest as nothing wrong, within its 15-minute grace, rather than reading not ok for the seconds before its first sync. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5eb0ea7760
commit
062ec07f0a
+5
-2
@@ -16,11 +16,11 @@ import { pushReport } from './master-link';
|
||||
import { getBuildVersion } from './version';
|
||||
import { tradeMixFor } from './trade-mix';
|
||||
import { updaterStatus } from './updater-status';
|
||||
import { getClients } from './clients';
|
||||
import { getClients, isResting } from './clients';
|
||||
import { getAccountTypeById, getKeptRuleIdsForFirm, getTradableFirms } from './firm-catalog';
|
||||
import { getAccountConfig } from './account-type-resolver';
|
||||
import { getSchedulerStatus } from './auto-trade';
|
||||
import { botStopsActive, combineCmeSessions, computeDayPlan, currentTradeDateCT, cycleCompletion, endedCycleCompletion, LEG_COMPLETION_EPSILON, projectPerfectPath, resolveEffectiveConfig } from './trading-logic';
|
||||
import { botStopsActive, combineCmeSessions, computeDayPlan, currentTradeDateCT, cycleCompletion, endedCycleCompletion, LEG_COMPLETION_EPSILON, projectPerfectPath, resolveEffectiveConfig, restSnapshotStale } from './trading-logic';
|
||||
import type { AccountTypeStats, FirmStats, InstrumentStats, SymbolStats } from './master-protocol';
|
||||
import { accountNextLeg, accountLegShape } from './leg-estimate';
|
||||
import { sizingHoldHours } from './person-size';
|
||||
@@ -49,6 +49,9 @@ function collectFirmStats() {
|
||||
const keptRuleIds = getKeptRuleIdsForFirm(f.id);
|
||||
// accounts: [] only once synced (see emptyFirmStats).
|
||||
if (!client || client.accountList.length === 0) return emptyFirmStats(f, client, keptRuleIds);
|
||||
// A rest that spans the 5 PM roll holds yesterday's snapshot: unsynced
|
||||
// until it logs back in, not yesterday's trading counted as today's.
|
||||
if (isResting(f.id) && restSnapshotStale(client.lastSyncAt)) return emptyFirmStats(f, undefined, keptRuleIds);
|
||||
|
||||
let totalAccounts = 0;
|
||||
let accountsTraded = 0;
|
||||
|
||||
@@ -1889,6 +1889,17 @@ export function planRest(
|
||||
return { wakeAt, checkInAt: planCheckIn(now, wakeAt, rand), leadMs };
|
||||
}
|
||||
|
||||
/**
|
||||
* A resting session's snapshot, last synced at `lastSyncAt`, is from an
|
||||
* earlier trade date than `now`: its realized P&L, DLL lockouts and legs are
|
||||
* the old day's, and counted as today's they would read as accounts already
|
||||
* traded. It reports as unsynced until the session logs back in.
|
||||
*/
|
||||
export function restSnapshotStale(lastSyncAt: number, now: number = Date.now()): boolean {
|
||||
if (!(lastSyncAt > 0)) return true;
|
||||
return currentTradeDateCT(new Date(lastSyncAt)) !== currentTradeDateCT(new Date(now));
|
||||
}
|
||||
|
||||
/**
|
||||
* A firm's cap on how many of its accounts trade at once, on top of the
|
||||
* machine's own max concurrent accounts: keeps `items` in order, at most
|
||||
|
||||
Reference in New Issue
Block a user