diff --git a/config/training/dqn-smoketest.toml b/config/training/dqn-smoketest.toml index 1617eb307..b07de743b 100644 --- a/config/training/dqn-smoketest.toml +++ b/config/training/dqn-smoketest.toml @@ -22,6 +22,9 @@ reward_scale = 1.0 huber_delta = 1.0 symbol = "ES.FUT" max_bars = 5000 +data_source = "ohlcv" +mbp10_data_dir = "test_data/futures-baseline-mbp10" +trades_data_dir = "test_data/futures-baseline-trades" imbalance_bar_threshold = 1.0 imbalance_bar_ewma_alpha = 0.1 diff --git a/crates/ml/src/trainers/dqn/data_loading.rs b/crates/ml/src/trainers/dqn/data_loading.rs index 1b57fcb61..4b01c024b 100644 --- a/crates/ml/src/trainers/dqn/data_loading.rs +++ b/crates/ml/src/trainers/dqn/data_loading.rs @@ -100,18 +100,29 @@ impl DQNTrainer { )> { // ── fxcache discovery (strict key match via shared function) ──────── let cache_dir_override = self.feature_cache_dir.as_deref(); - let mbp10_path = if self.hyperparams.mbp10_data_dir.is_empty() { + // Resolve mbp10/trades paths — try as-is first, then relative to workspace root + // (CARGO_MANIFEST_DIR points to crates/ml, workspace root is 2 levels up). + let resolve_data_path = |raw: &str| -> Option { + if raw.is_empty() { return None; } + let p = std::path::Path::new(raw); + if p.exists() { return Some(p.to_path_buf()); } + // Try relative to workspace root + if let Ok(manifest) = std::env::var("CARGO_MANIFEST_DIR") { + if let Some(root) = std::path::Path::new(&manifest).parent().and_then(|p| p.parent()) { + let abs = root.join(raw); + if abs.exists() { return Some(abs); } + } + } + // Try relative to dbn_data_dir's parent (e.g. test_data/futures-baseline → test_data/) + let parent = std::path::Path::new(dbn_data_dir).parent().unwrap_or(std::path::Path::new(".")); + let sibling = parent.join(std::path::Path::new(raw).file_name().unwrap_or_default()); + if sibling.exists() { return Some(sibling); } None - } else { - let p = std::path::Path::new(&self.hyperparams.mbp10_data_dir); - if p.exists() { Some(p) } else { None } - }; - let trades_path = if self.hyperparams.trades_data_dir.is_empty() { - None - } else { - let p = std::path::Path::new(&self.hyperparams.trades_data_dir); - if p.exists() { Some(p) } else { None } }; + let mbp10_resolved = resolve_data_path(&self.hyperparams.mbp10_data_dir); + let trades_resolved = resolve_data_path(&self.hyperparams.trades_data_dir); + let mbp10_path = mbp10_resolved.as_deref(); + let trades_path = trades_resolved.as_deref(); if let Some(cached) = crate::fxcache::discover_and_load( std::path::Path::new(dbn_data_dir),