fix: test_data_dir returns base dir for fxcache key match
test_data_dir() was returning the symbol-specific path (test_data/futures-baseline/ES.FUT) causing fxcache key mismatch — the cache was created with the base dir. Now returns the parent directory so trainer.train(data_dir, "ES.FUT", ...) can discover the fxcache via matching cache key. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -125,37 +125,45 @@ pub(super) fn load_smoke_data() -> anyhow::Result<(
|
||||
Ok((train, val))
|
||||
}
|
||||
|
||||
/// Resolve single-symbol test data directory.
|
||||
/// Resolve base data directory containing symbol subdirectories.
|
||||
///
|
||||
/// Returns the PARENT of the symbol directory (e.g. `test_data/futures-baseline`),
|
||||
/// not the symbol-specific path. Callers pass the symbol separately to
|
||||
/// `trainer.train(data_dir, "ES.FUT", ...)` which enables fxcache key matching
|
||||
/// (the cache key hashes all files at data_dir, not just one symbol).
|
||||
///
|
||||
/// Uses `FOXHUNT_TEST_DATA` env var if set, otherwise auto-detects
|
||||
/// `test_data/ES.FUT` relative to the workspace root.
|
||||
/// Returns `None` if the directory doesn't exist.
|
||||
/// relative to the workspace root. Returns `None` if no data found.
|
||||
pub(super) fn test_data_dir() -> Option<String> {
|
||||
// Check env vars: FOXHUNT_TEST_DATA (explicit), TEST_DATA_DIR (CI PVC root)
|
||||
for var in &["FOXHUNT_TEST_DATA", "TEST_DATA_DIR"] {
|
||||
if let Ok(dir) = std::env::var(var) {
|
||||
let path = std::path::Path::new(&dir);
|
||||
// Search for ES.FUT in common layouts:
|
||||
// 1. $DIR/ES.FUT (direct)
|
||||
// 2. $DIR/ohlcv/ES.FUT (CI PVC layout)
|
||||
// If the env var points directly at a symbol dir, return its parent
|
||||
if path.file_name().and_then(|n| n.to_str()) == Some("ES.FUT") {
|
||||
if let Some(parent) = path.parent() {
|
||||
return Some(parent.to_string_lossy().into_owned());
|
||||
}
|
||||
}
|
||||
// Check if ES.FUT exists as a subdirectory
|
||||
for sub in &["ES.FUT", "ohlcv/ES.FUT"] {
|
||||
let candidate = path.join(sub);
|
||||
if candidate.exists() {
|
||||
return Some(candidate.to_string_lossy().into_owned());
|
||||
if path.join(sub).exists() {
|
||||
return Some(path.to_string_lossy().into_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Auto-detect from workspace root: test_data/ES.FUT or test_data/ohlcv/ES.FUT
|
||||
// Auto-detect from workspace root
|
||||
let manifest = std::env::var("CARGO_MANIFEST_DIR").unwrap_or_default();
|
||||
let workspace = std::path::Path::new(&manifest)
|
||||
.parent() // crates/
|
||||
.and_then(|p| p.parent()) // repo root
|
||||
.unwrap_or(std::path::Path::new("../.."));
|
||||
let test_data = workspace.join("test_data");
|
||||
for sub in &["futures-baseline/ES.FUT", "ES.FUT", "ohlcv/ES.FUT"] {
|
||||
let candidate = test_data.join(sub);
|
||||
if candidate.exists() {
|
||||
// Return the base dir that contains ES.FUT as a subdirectory
|
||||
for base in &["futures-baseline", ".", "ohlcv"] {
|
||||
let candidate = test_data.join(base);
|
||||
if candidate.join("ES.FUT").exists() {
|
||||
return Some(candidate.to_string_lossy().into_owned());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user