Fifth review round (1eb0736):
- An entry now has three outcomes. Filled (confirmed): one-and-done is done
for the day. Never placed: leg taken back, free to retry. Unknown (an ack
or fill that never came back): the account — any mode — is held until a
good sync at least 90s later shows it flat with realized P&L unchanged,
then the leg is taken back and it may retry. Stop-after-all counts it in
play meanwhile. This closes both the day-long bench of 52ed9c7 and the
stacked re-entries of 1eb0736.
- Tradovate cancels an acked order whose fill didn't come within 30s (as
TopstepX already does), so a retry can't sit beside a still-working one.
- A wipe keeps the rebuild's guards: wipeAccountData leaves the Cash History
baseline, roll base, wipe hold, pre-wipe fund signature and the
resolver's inferred size in account_meta; the routes forget history
before wiping (so the stored rows are still there to read), and a wipe
hold restored after a restart keeps its pre-wipe yardstick.
- Wipe routes take the set of typed accounts before wiping, so an account
the resolver un-assigns mid-rebuild still counts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fourth review round (52ed9c7):
- The one-and-done guard counts only entries the broker confirmed filled,
so an entry that timed out or was rejected unfilled no longer benches the
account for the day.
- TopstepX: an account is promoted only by a sync that actually checked its
funds; one with no account type stays out (not traded) without costing a
sync per pass, and once typed waits for that check. Wipe routes don't
count untyped accounts as failures.
- Tradovate: an unchecked balance-hold release needs Cash History refused
for a full hour straight (a 4xx other than 401/403/408/429, or an answer
without data); any other outcome resets it, so one stray reply during a
5xx outage can't release a payout.
- A wipe keeps the pre-wipe baseline and fund rows as its yardstick: the
rebuild must explain today's balance against them, so a payout the
rebuilt report hasn't booked yet stays held.
- The roll base of an unrolled record is kept per trade date in
account_meta, so a restart later the same trade date counts from the same
point instead of from a value that already includes the day's fills.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Both clients track which accounts this process has loaded history for
(historyReady). An account restarted, rebuilt, wiped or newly listed is
ineligible until its fetch lands, instead of trading as a fresh stage-1
first day; a failed fetch with no cache no longer reads as empty history.
Waiting accounts get a targeted fetch on the next sync.
- Tradovate holds an account whose start-of-day balance moves without a fill
(a payout between hourly Cash History runs) until a Cash History books it,
so a payout-pending account isn't re-traded on its ended cycle.
- Wipe routes forget history through the client and count accounts whose
history didn't come back as failures.
- TopstepX sendOrder picks up a fill that arrived before the place response,
and its REST backstop uses the documented Trade/search and Order/search.
- POINT_VALUES: SI 5000 (was 50), M2K 5 (was 10).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cached daily P&L rows outlive what the Cash History report still
produces (stale pre-roll dates being the recent example), and nothing
deletes them any more. POST /api/accounts/[id]/wipe drops the account's
cached P&L, fund transactions and meta, clears the in-memory view, and
rebuilds from a fresh report — fetchDaysTraded now takes an optional
account filter so one account doesn't cost a report round-trip on every
other. The button confirms inline first: rows older than the report's
28-day window cannot be refetched.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>