feat(phase-e-4-a-T16): vol-regime detection + cost-aware training
Adds two coupled interventions on the regime fragility exposed by
walk-forward CV (mean Sharpe +27 ± 56 at half-tick across 3 folds —
std-dev ≈ mean means the strategy is regime-dependent).
(1) Vol-EMA regime detector (new ISV slots 549/550)
- New alpha_regime_vol_update.cu kernel: per inference step, reads B
parallel-env mid prices, computes cross-env mean squared log-return,
and maintains ISV[549]=REGIME_VOL_EMA (Wiener-α with 0.4 floor +
Pearl A bootstrap) and ISV[550]=REGIME_VOL_REF (slow tracker β=0.005,
≈200-step horizon).
- Block-tree-reduce (no atomicAdd), guards against zero/non-finite mids.
(2) Pre-emptive Kelly attenuation (modified stacker controller)
- stacker_threshold_controller.cu takes 3 new args: regime_vol_ema_idx,
regime_vol_ref_idx, regime_scale_floor.
- Multiplies its reactive Sharpe-error Kelly output by
regime_scale = clamp(vol_ref / vol_ema, 0.25, 1.0)
- Disabled when indices = -1 (backward-compatible smoke + kernel test).
(3) Cost-aware training (--train-cost-hi)
- alpha_compose_backtest --train-cost-hi: when > --train-cost, each
training epoch samples cost ~ U[lo, hi] so the Q-network learns
cost-conservative behaviour across the realistic ES range.
(4) Wiring
- alpha_compose_backtest --regime-scale enables both per-step regime
kernel firing during eval AND the regime hookup in the per-episode
controller call. Mapped-pinned mids buffers, all compute device-side.
- ExecutionEnv exposes current_mid() so the host gather reads the
active snapshot mid per env without leaking the private cursor field.
Smoke + test sites pass -1/-1 for regime indices (backward compat).
Doc: docs/isv-slots.md ledger for slots 549/550.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -847,3 +847,69 @@ NO ISV slot interaction — both kernels operate purely on the smoke /
|
||||
backtest binary's `window_dev` and `h_enriched_buf_dev` buffers.
|
||||
Documented here only for the kernel-audit-doc hook requirement;
|
||||
truly slot-agnostic.
|
||||
|
||||
## 2026-05-16 — Phase E.4.A T16 vol-EMA regime detection (slots 549/550)
|
||||
|
||||
Walk-forward CV across Q1 2024 (3 folds, 700K-bar windows) exposed
|
||||
that the T10 architecture has mean Sharpe +27 ± 56 at half-tick cost
|
||||
(std-dev ≈ mean → regime-dependent learning). Fold B in particular
|
||||
collapsed to -21..-60 across all costs with 0-22% win rate. T16
|
||||
adds two coupled defenses.
|
||||
|
||||
**Slot 549 — REGIME_VOL_EMA_INDEX**
|
||||
- Producer: `alpha_regime_vol_update.cu::alpha_regime_vol_update_kernel`
|
||||
- Update cadence: per inference step (every env step during eval; off
|
||||
during training unless explicitly wired)
|
||||
- Math: reduce mids across B parallel envs to mean(log(curr/prev))²,
|
||||
EMA-update via Wiener-α with floor 0.4 + Pearl A bootstrap.
|
||||
- Consumer: modified `stacker_threshold_controller.cu` Kelly branch
|
||||
reads slot 549 + slot 550 to compute pre-emptive scale.
|
||||
- Sentinel: 0.0. First-observation bootstrap replaces directly.
|
||||
|
||||
**Slot 550 — REGIME_VOL_REF_INDEX**
|
||||
- Producer: same kernel; β=0.005 (≈200-step horizon) so it tracks the
|
||||
slow-moving "what is the trained regime" reference. Acute spikes do
|
||||
NOT pollute the reference, preserving the spike-detector property
|
||||
of `vol_ema / vol_ref`.
|
||||
- Sentinel: 0.0. First-observation bootstrap copies the bootstrapped
|
||||
vol_ema so the spike-detector ratio starts at 1.0 (no spurious
|
||||
early attenuation).
|
||||
|
||||
**Producer kernel — `alpha_regime_vol_update.cu`:**
|
||||
- Single-block, ≤256-thread block-tree reduction over B mids; no
|
||||
atomicAdd per `feedback_no_atomicadd`. Guards against zero /
|
||||
non-finite mids (B can be 50 eval envs, some may have done==1
|
||||
earlier in the episode and their mids will be stale 0.0).
|
||||
- All compute device-side per `feedback_cpu_is_read_only`. Mids
|
||||
themselves are written via mapped-pinned f32 buffers (host gather
|
||||
is one f32 per env per step, no htod copy).
|
||||
|
||||
**Consumer change — `stacker_threshold_controller.cu`:**
|
||||
- Signature gains `regime_vol_ema_idx`, `regime_vol_ref_idx`,
|
||||
`regime_scale_floor` args. When indices ≥ 0 AND `vol_ref > 0` AND
|
||||
`vol_ema > 0`, the Kelly output is scaled by
|
||||
`clamp(vol_ref / vol_ema, regime_scale_floor=0.25, 1.0)`. When
|
||||
indices = -1 the scale collapses to 1.0 (backward-compatible — both
|
||||
the smoke binary and the kernel unit test pass -1/-1).
|
||||
- Reactive (Sharpe-error) and pre-emptive (vol-spike) components
|
||||
compose multiplicatively. Pre-emptive fires AS SOON AS vol blows
|
||||
past trained-on reference; reactive only fires AFTER P&L pain.
|
||||
|
||||
**Backtest CLI:**
|
||||
- `--regime-scale` enables both the per-step regime kernel firing
|
||||
during eval AND the regime hookup in the per-episode controller
|
||||
call (requires `--isv-continual` for the controller path).
|
||||
- `--train-cost-hi <hi>` (combined with `--train-cost <lo>`): per
|
||||
training epoch samples cost ~ U[lo, hi]. Default lo=hi=0.0625 =
|
||||
backward compat (no randomization). The T16 hypothesis is that
|
||||
cost-randomized training + vol-regime defense together close the
|
||||
Fold B failure mode.
|
||||
|
||||
**Verification (when Q1+Q2 2024 fxcache builds complete):** walk-forward
|
||||
CV across Q1↔Q2 boundary with all four configurations:
|
||||
- T10 baseline (no regime, fixed cost)
|
||||
- T10 + cost randomization only
|
||||
- T10 + regime scale only
|
||||
- T10 + both
|
||||
Expected: combined config compresses cross-fold std-dev meaningfully
|
||||
without sacrificing best-fold Sharpe.
|
||||
|
||||
Reference in New Issue
Block a user