From 1aaf94306c1759c60e0f11b654f22f2d53f38d32 Mon Sep 17 00:00:00 2001 From: jgrusewski Date: Sat, 9 May 2026 21:41:22 +0200 Subject: [PATCH] =?UTF-8?q?fix(wgdc8):=20bypass=20EWMA=20adaptation=20in?= =?UTF-8?q?=20ImbalanceBarSampler=20=E2=80=94=20use=20fixed=20threshold?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this, the configured imbalance_bar_threshold is washed out within ~5 bars by the adaptive EWMA recursion (T_new = 0.1·T_old + 0.9·observed; with α=0.1, half-life under 1 bar, fixed point = data's natural imbalance scale). The bar-resolution smoke test would have been comparing two identical equilibria, not two different resolutions. Switch mbp10_to_imbalance_bars from `new_with_ewma()` to `new()` so the configured threshold (= 2.5 on this branch, 5× the production 0.5) actually holds for the entire run. Cache-key continuity preserved (ewma_alpha still hashed and logged). Architectural follow-up: 16+ prior SP runs likely had configured-threshold- washout silently. Whether they were all measuring "ES.FUT MBP-10 equilibrium imbalance scale" regardless of the threshold value in their TOML is worth a separate investigation. Out of scope for this branch. Co-Authored-By: Claude Opus 4.7 (1M context) --- crates/ml-features/src/mbp10_loader.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/crates/ml-features/src/mbp10_loader.rs b/crates/ml-features/src/mbp10_loader.rs index b08986c1d..de1ff6641 100644 --- a/crates/ml-features/src/mbp10_loader.rs +++ b/crates/ml-features/src/mbp10_loader.rs @@ -661,8 +661,16 @@ pub fn mbp10_to_imbalance_bars( // Sort by timestamp (files should be chronological but ensure correctness) all_trades.sort_by(|a, b| a.timestamp.cmp(&b.timestamp)); - tracing::info!( - "Extracted {} trade ticks, feeding into ImbalanceBarSampler (threshold={}, alpha={})", + // wgdc8 experiment: EWMA adaptation bypassed. With α=0.1 the configured + // threshold is washed out within ~5 bars (recursion: T_new = 0.1·T_old + + // 0.9·observed; fixed point is the data's natural imbalance scale, not + // the configured value). To make `imbalance_bar_threshold` actually + // honored — and the resolution-hypothesis smoke meaningful — use the + // fixed-threshold constructor. ewma_alpha=0.1 is logged for cache-key + // continuity but does not drive bar formation on this branch. + tracing::warn!( + "wgdc8: EWMA adaptation BYPASSED. Feeding {} trade ticks into \ + ImbalanceBarSampler with FIXED threshold={} (config alpha={} ignored)", all_trades.len(), threshold, ewma_alpha, @@ -671,7 +679,7 @@ pub fn mbp10_to_imbalance_bars( // Initialize sampler with first trade let first = &all_trades[0]; let mut sampler = - ImbalanceBarSampler::new_with_ewma(first.price, threshold, first.timestamp, ewma_alpha); + ImbalanceBarSampler::new(first.price, threshold, first.timestamp); let mut bars: Vec = Vec::new(); for trade in &all_trades {