Unknown entries: judge only on a fresh good sync; all live orders count as working

Seventh review round (57835c0):

- An entry of unknown outcome is judged — filled after all, or never
  filled — only on a good sync that started after its settle window and
  with no order still working. A partial pass (position read failed or
  predated the fill, trades read after it) can no longer release it as
  "filled and flat" into a second entry.
- Tradovate counts every order not Filled/Canceled/Rejected/Expired/
  Completed as working (PendingCancel, Unknown included).
- TopstepX: an account whose order ended with its outcome unknown gets its
  open orders checked (Order/searchOpen) on each sync until none show, and
  counts as holding a working order until then.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Brandon Li
2026-09-24 22:13:47 -05:00
co-authored by Claude Opus 5.5
parent 57835c01f0
commit 809f337055
3 changed files with 53 additions and 10 deletions
+4 -3
View File
@@ -103,8 +103,9 @@ const TOKEN_REUSE_MIN_MS = 5 * 60_000;
/** An order ack later than this is treated as lost (ambiguous — it may have been placed). */
const ACK_TIMEOUT_MS = 15_000;
const FILL_TIMEOUT_MS = 30_000;
/** Order states that can still fill (Tradovate ordStatus). */
const WORKING_ORDER_STATUSES = new Set(['Working', 'PendingNew', 'PendingReplace', 'Suspended']);
/** Order states that can no longer fill (Tradovate ordStatus); any other —
* Working, PendingNew/Replace/Cancel, Suspended, Unknown — still might. */
const FINISHED_ORDER_STATUSES = new Set(['Filled', 'Canceled', 'Rejected', 'Expired', 'Completed']);
/** How far the start-of-day balance may move without a fill before the
* account's history is treated as overtaken (balanceDrifted). Fills move
* amount and realizedPnL together, so this only has to absorb rounding;
@@ -1017,7 +1018,7 @@ export class TradovateClient {
const working: { [accountId: number]: number } = {};
for (const order of (response.orders ?? []) as { accountId?: number; ordStatus?: string }[]) {
if (order.accountId && WORKING_ORDER_STATUSES.has(order.ordStatus ?? '')) {
if (order.accountId && !FINISHED_ORDER_STATUSES.has(order.ordStatus ?? '')) {
working[order.accountId] = (working[order.accountId] ?? 0) + 1;
}
}