fix(critical): MTF features were overwriting plan progress in observation

Portfolio expanded from 8→14 features but mtf_base stayed at
market_dim+8, causing MTF to overwrite plan progress features.
Fixed: mtf_base = market_dim + 14. Layout now correct:
[0..42) market, [42..56) portfolio+plan, [56..72) MTF, [72..92) OFI.
state_dim stays 96 (aligned). Conviction drift + regime shift (P11/P12)
added to observation. Entry regime_stability stored in ps[29].

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2026-04-17 09:21:54 +02:00
parent 7651f6f6cc
commit 3ce8ed40f1
2 changed files with 4 additions and 4 deletions

View File

@@ -629,7 +629,7 @@ extern "C" __global__ void experience_state_gather(
* +3: momentum = close_now vs midpoint of N-bar range (0=bottom, 1=top)
*/
const int lookbacks[4] = {5, 15, 60, 240};
int mtf_base = market_dim + 8;
int mtf_base = market_dim + 14; /* after 14 portfolio features (8 base + 6 plan) */
for (int lb = 0; lb < 4; lb++) {
int Nlb = lookbacks[lb];
int past_idx = bar_idx - Nlb;

View File

@@ -49,8 +49,8 @@ impl DQNTrainer {
// Align input_dim to 8 so the log matches the actual model dimensions.
// (device not yet created, so use the formula directly -- CUDA always aligns)
let ofi_pre = !hyperparams.mbp10_data_dir.is_empty();
// 42 market + 12 portfolio (8 base + 4 plan progress) + 16 multi-timeframe = 70 base, +20 OFI = 90
let input_dim: usize = if ofi_pre { 96 } else { 72 }; // (90+7)&!7=96, (70+7)&!7=72
// 42 market + 14 portfolio (8 base + 6 plan) + 16 multi-timeframe = 72 base, +20 OFI = 92
let input_dim: usize = if ofi_pre { 96 } else { 72 }; // (92+7)&!7=96, (72+7)&!7=72
let output_dim: usize = 5;
let hidden_dims: Vec<usize> = match hyperparams.hidden_dim_base {
Some(base) => {
@@ -252,7 +252,7 @@ impl DQNTrainer {
// of falling back to scalar FMA. The extra columns are zero-padded at the
// data pipeline boundaries (GpuPreloadedData and train_batch CPU path).
let ofi_enabled = !hyperparams.mbp10_data_dir.is_empty();
let raw_state_dim: usize = if ofi_enabled { 90 } else { 70 }; // 42 market + 12 portfolio + 16 MTF + (20 OFI)
let raw_state_dim: usize = if ofi_enabled { 92 } else { 72 }; // 42 market + 14 portfolio + 16 MTF + (20 OFI)
let full_state_dim = (raw_state_dim + 7) & !7; // aligned: 88 with OFI, 72 without
// state_dim is always the FULL padded dimension. The GpuDqnTrainer