Files
foxhunt/crates/ml-alpha/tests
jgrusewski 5e4c2e62b6 fix(rl): CMDP DD recovery + IQN τ reads mean-of-active (not worst)
Diagnosed via the diag-emit added in 6e0f56816 — alpha-rl-d6d8d step 2000
showed worst-account at -$18k, IQN τ pinned at floor 0.1, popart σ
collapsing 1.00 → 0.47. Root cause: dead-account accumulation in a
sticky-DD fleet.

The per-batch CMDP from 39efacf77 fixed the GLOBAL lockout but left
two failure modes:

  1. Once an account hit `dd_limit`, `session_dd_triggered_per_batch[b]`
     stayed sticky for the fold. `actions_to_market_targets` forced
     those accounts to no-op → V_target ≈ γ·V(s'_unchanged) → popart
     σ leaked variance from accumulating dead-weight.

  2. ISV[RL_SESSION_PNL_USD_INDEX] exposed worst-account pnl, which
     IQN-τ consumes for `drawdown_frac`. A single broken account
     dragged τ to its floor for the entire fold — defensive action
     selection for a fleet that was, on average, doing fine.

Fix A: DD recovery on cooldown expiry. When `dd_limit` trips, also
start a recovery cooldown clock. When the clock decrements to 0,
clear `dd_triggered` + reset `session_pnl` to 0. Account rejoins the
active fleet. Matches surfer trading philosophy: accept the wipeout,
take the forced break, get back on the board.

Fix B: IQN-τ signal split. CMDP now writes mean-of-active-accounts
to RL_SESSION_PNL_USD_INDEX (slot 662, IQN-τ consumer) and mirrors
worst per-batch pnl to a new slot RL_SESSION_PNL_WORST_INDEX (684,
diag only). τ now tracks fleet-typical drawdown instead of a single
catastrophic outlier.

Subtle kernel detail caught by G1: `cool_prev` must be snapshotted
BEFORE the DD-trip section, otherwise a fresh cooldown set this step
gets immediately decremented by 1 in the same launch.

Validation (local b=128 1k smoke):
  metric            | pre-fix (HEAD) | with A+B
  worst pnl          | -$34,016       | -$7,183     (79% less bleed)
  mean active pnl    | n/a            | +$40,343    (typical account profitable)
  IQN τ              | 0.10 (floored) | 0.50        (neutral)
  popart σ           | 0.47→collapsing| 0.84        (variance preserved)
  win rate           | 0.21           | 0.56        (positive edge)

13/13 risk_stack_invariants pass (G1 updated, G1b NEW for cooldown
recovery). 20/20 trade_management_kernels pass. integrated_trainer_smoke
end-to-end passes.

Slot 684 added: RL_SESSION_PNL_WORST_INDEX. RL_SLOTS_END 684 → 685.
2026-05-30 22:40:36 +02:00
..