Plan slots: target_bars, profit_target, stop_loss, scale_aggression,
conviction, asymmetry, counter_plan_q. Zeroed on episode reset.
Fixed hardcoded i*23 references. All CUDA + Rust files updated.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backtest evaluator missing isv_signals_ptr arg (passed as NULL).
Regenerated test fxcache with OFI_DIM=20 from MBP-10 + trades data.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
mbp10_data_dir and trades_data_dir uncommented in localdev config.
Doc comments updated: 20 microstructure features always appended.
OFI is no longer optional — it's core to the model's feature set.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
isv_feature_gate kernel: ISV embedding [8] → per-feature gate [SH2].
h_s2 *= sigmoid(w_gate @ isv_emb + b_gate). Near pass-through init
(bias=2.0 → sigmoid≈0.88). Model learns to amplify/suppress features
based on ISV state. 2 new tensors [78-79]. NUM_WEIGHT_TENSORS: 78→80.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
w_risk_fc grows from AH*(SH2+9) to AH*(SH2+13). Risk branch now
sees all 12 ISV signals (including 4 regime: velocity, disagreement,
transition_ema, stability) + predicted_error. Forward + backward
updated with wider stride and 12-signal loop.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Portfolio slots ps[15]-ps[19] are Kelly accumulators (active).
Plan params moved to ps[23]-ps[29]. PORTFOLIO_STRIDE grows 23→30.
Fixed asymmetry: scales profit_target only (not stop_loss).
Clarified epsilon mid-plan: overridden by direction lock (intended).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
mamba2_temporal_scan forget gate multiplied by regime_stability (ISV[11]).
Stable regime (stability=1.0): full history preserved.
Transition (stability=0.3): gate capped at 0.3 → rapid forgetting.
Model adapts to new regime within 2-3 bars. Backward matches forward.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
12 new tick-level features computed per bar from MBP-10 snapshots:
OFI trajectory, realized variance, Hawkes intensity, book pressure,
spread dynamics, aggression, queue depletion, order count flux,
intra-bar momentum, regime score, OFI acceleration, toxicity gradient.
Combined with existing 8 OFI into [f64; 20] per bar in fxcache.
Also fixes pre-existing bug: no-MBP-10 fallback was [0.0; 8] not [0.0; 20].
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fxcache: OFI_DIM=20 (pub const), RECORD_F64_COUNT=66, 272 bytes/bar.
constructor: state_dim 74→86 (aligned 88) with OFI.
experience collector: ofi_dim detection 8→20.
All [f64; 8] → [f64; 20]. Existing 8 features preserved at 0-7.
New 12 features zero-padded until precompute is extended.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The hold enforcement infrastructure (enforce_hold in trade_physics.cuh,
hold_time counter at ps[10], action masking in experience_action_select)
was already fully implemented but disabled by min_hold_bars defaulting
to 1. Change default from 1 to 5 so hold enforcement is active by
default. Production configs already set min_hold_bars=10 via TOML.
Targets ~100-200K trades instead of 619K across 5M bars.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
EMA sync restricted to indices 0-67 (non-ISV params).
ISV weights (68-77) exist only in online params_buf.
Target forward uses online gamma_buf (drift-conditioned) and
online branch_gate_buf — correct for Bellman projection.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
h_s2 → sigmoid(w_conf @ h + b_conf) → predicted_error [B].
MSE loss vs lagged_td_error (0.01× weight). Backward accumulates
into trunk gradient + conf weight gradients in main grad_buf.
Creates self-improvement loop: model learns to predict when wrong.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8 ISV signals (q_drift, grad_norm_ema, td_error_ema, ensemble_var_ema,
ensemble_var_delta, reward_ema, atom_util, loss_ema) computed by
single-thread GPU kernel. Temporal history [K=4, 8] with ring buffer.
Lagged TD-error saved for recursive confidence. Zero CPU involvement.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
td_error_scratch, ensemble_var_scratch, reward_scratch, atom_util_scratch
— all pinned device-mapped. atom_util and reward_scratch written in
reduce_current_q_stats. td_error and ensemble_var wired in later tasks.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rank normalization: holding bars (reward≈0) passthrough as zero,
only actual trade P&L is ranked. Preserves magnitude for trades.
Q-drift: hardcoded penalty removed, E1 enrichment handles adaptively.
Metrics: sharpe_raw (un-annualized per-trade) for direct comparison
between training and validation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Components were fighting a broken signal, not broken themselves.
With correct signal: adapt DSR to trade-level, rank only non-zero
rewards, keep commitment as soft signal, let E1 enrichment handle
Q-drift instead of hardcoded kernel penalty.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause: training environment differs from validation backtest in 3 ways:
1. 100-bar episodes force exits (val runs continuous) → position-gated done
2. Rank normalization destroys sparse trade-level reward → remove it
3. Different Sharpe computation (per-trade vs per-bar, different annualization)
Single execution path:
Phase 1: Episode alignment (100→5000 bars, position-gated done, soft reset)
Phase 2: Reward alignment (remove rank norm, raw trade P&L to replay)
Phase 3: Metrics alignment (un-annualized per-trade Sharpe, both paths)
Expected: training Sharpe within 2× of validation with same weights.
Removes 5 unnecessary shaping components that fought the broken signal.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Q-mean drifted to +4.6 but E1 correction was capped at -2.0.
The model needs full correction range to keep Q-values calibrated.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
segment_pnl depended on raw_pnl (now zero after raw_next removal).
The trade-closing P&L was missing the final bar's unrealized gain/loss.
Fix: compute unrealized_at_exit = position * (raw_close - entry_price)
directly. No future price needed — just current close vs entry.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
E1 enrichment was computing q_corr = mean(predicted_q - pnl) but
predicted_q was set to avg_pnl → bias always ~0. Now uses actual
avg_q_value from the training step, producing meaningful corrections
when Q-values drift away from realized returns.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
portfolio_sim_kernel also used next_close_raw (future price) for
mark-to-market and reward computation. Fixed: use current price only.
Updated stale comments referencing per-bar reward in trade-level section.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The experience collector used raw_next (NEXT bar's close) for P&L and
equity, creating a 1-bar misalignment between actions and rewards.
The model couldn't learn which actions produce which outcomes.
val_Sharpe=24 (backtest uses raw_close correctly) but training Sharpe=0
(experience collector used raw_next, shifting reward by 1 bar).
Fix: ALL portfolio computations use raw_close only. raw_next removed
from reward path entirely. Rewards are per-trade only (position change
= realized P&L, holding = tiny cost, flat = zero).
This is the root cause of training Sharpe being capped at ~0 across
ALL runs regardless of model complexity or component changes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Post-validation enrichment: extract eval trades from WindowMetrics,
run all 8 enrichments, apply adaptive epsilon + gamma + agreement
threshold. Smoke test verifies enrichment runs at least once.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>