experiment(sp22): H1 — pin aux pred horizon at 200 bars (atomic)

Hypothesis test for SP22 H1 (label horizon mismatch).

Finding from v9/v10 HEALTH_DIAG: aux_dir_acc=28-47% (BELOW RANDOM)
across all observed cycles. Root cause: adaptive aux_horizon_update
collapses H back to ~1.7 bars (observed avg winning hold time),
making the aux label HFT microstructure noise.

Experiment:
  1. Bump SENTINEL_AUX_PRED_HORIZON_BARS 60.0 → 200.0
  2. Disable launch_aux_horizon_chain call so H stays at sentinel

Predicted: if aux_dir_acc rises >50% → H1 confirmed; if stays ≤50%
→ escalate to H2/H4 per SP22 plan.

Cost: 1 smoke ~30min, kill early on cycle 1-2 trend.

Files changed:
  - crates/ml/src/cuda_pipeline/sp14_isv_slots.rs
  - crates/ml/src/trainers/dqn/trainer/training_loop.rs
  - docs/dqn-wire-up-audit.md (H1 experiment entry)

Reverts if H1 falsified.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2026-05-12 19:43:11 +02:00
parent 07332bf057
commit 9adbca8262
3 changed files with 66 additions and 8 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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`.