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:
co-authored by
Claude Opus 5.5
parent
57835c01f0
commit
809f337055
+7
-6
@@ -158,19 +158,20 @@ function unknownEntryHolds(client: any, accountId: number, tradeDate: string): b
|
||||
const outcome = entryOutcomeToday(accountId, tradeDate);
|
||||
if (!outcome || outcome.state !== 'unknown') return false;
|
||||
const cash = client.accountCashBalances[accountId];
|
||||
// Nothing is judged before a good sync that started after the window:
|
||||
// until then a position read can predate the fill (or have failed) while
|
||||
// the trades read after it already show the P&L it booked.
|
||||
const syncedFrom = client.lastSyncStartedAt ?? client.lastSyncAt;
|
||||
if (syncedFrom < (outcome.unknownAt ?? outcome.at) + UNKNOWN_ENTRY_SETTLE_MS || cash === undefined) return true;
|
||||
if (client.hasWorkingOrders?.(accountId)) return true;
|
||||
// The broker shows the fill (the position, or the P&L it booked): it
|
||||
// filled after all. From here it's an ordinary filled entry — the
|
||||
// position gate holds it while open, one-and-done is done for the day.
|
||||
if (client.positions[accountId] || (cash && Math.abs(cash.realizedPnL - outcome.realizedBefore) >= 0.005)) {
|
||||
if (client.positions[accountId] || Math.abs(cash.realizedPnL - outcome.realizedBefore) >= 0.005) {
|
||||
outcome.state = 'filled';
|
||||
console.log(`[auto-trade] account ${accountId}: the entry of unknown outcome filled after all`);
|
||||
return false;
|
||||
}
|
||||
const syncedFrom = client.lastSyncStartedAt ?? client.lastSyncAt;
|
||||
const settled = syncedFrom >= (outcome.unknownAt ?? outcome.at) + UNKNOWN_ENTRY_SETTLE_MS
|
||||
&& cash !== undefined
|
||||
&& !client.hasWorkingOrders?.(accountId);
|
||||
if (!settled) return true;
|
||||
runtime().entryOutcomes?.delete(accountId);
|
||||
unrecordLeg(accountId, tradeDate, outcome.legAmount);
|
||||
console.log(`[auto-trade] account ${accountId}: the entry of unknown outcome never filled — free to trade again`);
|
||||
|
||||
Reference in New Issue
Block a user