diff --git a/crates/ml/src/cuda_pipeline/sp14_isv_slots.rs b/crates/ml/src/cuda_pipeline/sp14_isv_slots.rs index cc523f8bc..980a7461b 100644 --- a/crates/ml/src/cuda_pipeline/sp14_isv_slots.rs +++ b/crates/ml/src/cuda_pipeline/sp14_isv_slots.rs @@ -97,7 +97,15 @@ pub const AUX_PRED_HORIZON_BARS_INDEX: usize = 450; pub const AVG_WIN_HOLD_TIME_BARS_INDEX: usize = 451; // ── Aux horizon producer constants ──────────────────────────────────── -pub const SENTINEL_AUX_PRED_HORIZON_BARS: f32 = 60.0; // Pearl-A bootstrap +// SP22 H1 (2026-05-12) — bumped sentinel from 60 → 200. The adaptive +// `aux_horizon_update_kernel` was collapsing H back to ~1.7 (the +// observed avg winning hold time) because positions don't last long +// in our volume-bar setup. Result: aux head predicts 2-bar-ahead +// sign which is HFT microstructure noise, and aux_dir_acc pins at +// 28-47% (BELOW RANDOM!) across all cycles in v9/v10. To test H1, +// we force H=200 (≈156s @ volume bars) and disable the adaptive +// update so the label stays at a learnable horizon. +pub const SENTINEL_AUX_PRED_HORIZON_BARS: f32 = 200.0; // SP22 H1 fixed horizon pub const SENTINEL_AVG_WIN_HOLD_TIME_BARS: f32 = 0.0; // Pearl-A bootstrap pub const AUX_PRED_HORIZON_BARS_MIN: f32 = 1.0; // floor (cannot predict past) pub const AUX_PRED_HORIZON_BARS_MAX: f32 = 240.0; // ceiling (rollout buffer guard) diff --git a/crates/ml/src/trainers/dqn/trainer/training_loop.rs b/crates/ml/src/trainers/dqn/trainer/training_loop.rs index 365f87132..5839ede3d 100644 --- a/crates/ml/src/trainers/dqn/trainer/training_loop.rs +++ b/crates/ml/src/trainers/dqn/trainer/training_loop.rs @@ -457,13 +457,18 @@ impl DQNTrainer { let hold_at_exit_ptr = collector.hold_at_exit_per_sample_dev_ptr(); let trade_profitable_ptr = collector.trade_profitable_per_sample_dev_ptr(); let total_samples = (collector.alloc_episodes() * collector.alloc_timesteps()) as i32; - if let Err(e) = fused.trainer().launch_aux_horizon_chain( - hold_at_exit_ptr, - trade_profitable_ptr, - total_samples, - ) { - tracing::warn!(epoch, "launch_aux_horizon_chain failed (non-fatal): {e}"); - } + // SP22 H1 (2026-05-12) — adaptive horizon update DISABLED. + // The producer was collapsing H back to ~1.7 bars (avg winning + // hold time on volume bars), making the aux label "predict + // ~2-bar-ahead sign" = HFT noise. v9/v10 aux_dir_acc pinned + // at 28-47% (BELOW RANDOM) across all cycles. SP22 H1 test: + // force H = SENTINEL_AUX_PRED_HORIZON_BARS = 200 throughout + // training. If aux_dir_acc rises above 50%, longer-horizon + // labels are learnable; if it stays below, the aux head + // architecture itself can't learn directional signal at any + // horizon (escalates to SP22 H2/H4). + let _ = (hold_at_exit_ptr, trade_profitable_ptr); + // Note: total_samples used by launch_reward_cap_update below. // Class A P0-A (2026-05-08): adaptive REWARD_POS/NEG_CAP // — per-epoch boundary launch. Sweeps the per-sample // `step_ret_per_sample` + `trade_close_per_sample` buffers diff --git a/docs/dqn-wire-up-audit.md b/docs/dqn-wire-up-audit.md index ee4a03442..0f8962c30 100644 --- a/docs/dqn-wire-up-audit.md +++ b/docs/dqn-wire-up-audit.md @@ -16210,3 +16210,48 @@ configuration. New SP arc needed: - **Validation method**: each hypothesis gets its own atomic smoke with one variable changed; compare against v9 baseline (174 peak val, WR=50.1%). + +## 2026-05-12 — SP22 H1 experiment: pin aux horizon at 200 bars + +### Hypothesis + +`aux_dir_acc` pins at 28-47% (BELOW RANDOM) across v9/v10 cycles +because the adaptive `aux_horizon_update_kernel` collapses +ISV[AUX_PRED_HORIZON_BARS_INDEX=450] back to ~1.7 bars (the observed +`avg_winning_hold_time`). The aux head label becomes +`(p[bar+2] > p[bar])` — HFT-scale microstructure noise. With unlearnable +labels, the supervised aux supervision can't teach directional features +to the trunk → the WR=50% plateau in v5-v9. + +### Experiment scope + +1. Bump `SENTINEL_AUX_PRED_HORIZON_BARS` from 60.0 → 200.0 + (~156s @ volume bars at 0.78s/bar — multi-bar context window). +2. Disable `launch_aux_horizon_chain` call so H stays pinned at the + sentinel throughout training. + +### Predicted outcomes + +- H1 CONFIRMED if `aux_dir_acc` rises above 50% at H=200. Fix: replace + adaptive H with a fixed long horizon, or change H's driver from + avg_win_hold_time to something less collapsible. +- H1 FALSIFIED if `aux_dir_acc` stays ≤50% at H=200. Aux head can't + learn direction at any horizon — escalate to SP22 H2 (action-space + pathology) or H4 (feature representation gap). + +### Files changed + +- `crates/ml/src/cuda_pipeline/sp14_isv_slots.rs`: + `SENTINEL_AUX_PRED_HORIZON_BARS: 60.0 → 200.0` +- `crates/ml/src/trainers/dqn/trainer/training_loop.rs`: + `launch_aux_horizon_chain` call DISABLED (preserves sentinel). + +### Cost + kill criteria + +1 smoke, ~30 min wall-clock. Kill at cycle 2 if `aux_dir_acc` trend +is clear (per `feedback_kill_runs_on_anomaly_quickly`). + +### Reverts + +If H1 falsified → revert both files, proceed to H2/H3/H4 per the SP22 +plan at `docs/plans/2026-05-12-sp22-wr-plateau-investigation.md`.