fix: hyperopt preload loads fxcache directly (skip key mismatch)

The preload's key-based fxcache lookup failed because the cache key
hash depends on file metadata (size+mtime) which differs between
the precompute pod and hyperopt pod (different PVC mount paths).

Fix: load the first .fxcache file from the cache directory directly.
The precompute step generates exactly one fxcache per dataset — no
ambiguity. Eliminates 285s DBN fallback loading.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2026-04-07 14:20:49 +02:00
parent d18b386be3
commit 24e12dc93a

View File

@@ -832,31 +832,18 @@ impl DQNTrainer {
// ── Step 2: Try loading from fxcache ────────────────────────────────
let fxcache_data: Option<crate::fxcache::FxCacheData> = fxcache_dir.and_then(|cache_dir| {
let data_dir_path = &self.dbn_data_dir;
// Resolve relative paths against workspace root (CWD may be crates/ml during tests)
let resolve = |raw: Option<&str>| -> Option<PathBuf> {
let s = raw?;
let p = PathBuf::from(s);
if p.exists() { return Some(p); }
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(s);
if abs.exists() { return Some(abs); }
}
}
None
};
let mbp10 = resolve(self.mbp10_data_dir.as_deref());
let trades = resolve(self.trades_data_dir.as_deref());
let key_hex = crate::feature_cache::calculate_dbn_cache_key_full(
data_dir_path, mbp10.as_deref(), trades.as_deref(),
&self.symbol, &self.data_source,
).ok()?;
let key: [u8; 32] = hex::decode(&key_hex).ok()?.try_into().ok()?;
let path = crate::fxcache::find_fxcache(&cache_dir, &key)?;
match crate::fxcache::load_fxcache(&path) {
// Load the first .fxcache file from the cache directory.
// The precompute step generates exactly one fxcache per dataset.
// Key-based lookup fails when MBP-10/trades paths differ between
// the precompute pod and the hyperopt pod (different PVC mounts).
let fxcache_path = std::fs::read_dir(&cache_dir).ok()?
.flatten()
.find(|e| e.path().extension().map_or(false, |ext| ext == "fxcache"))
.map(|e| e.path())?;
info!("Loading fxcache from {:?}", fxcache_path);
match crate::fxcache::load_fxcache(&fxcache_path) {
Ok(data) => {
info!("fxcache hit: {} bars from {:?}", data.bar_count, path);
info!("fxcache hit: {} bars from {:?}", data.bar_count, fxcache_path);
Some(data)
}
Err(e) => {