fix(wgdc8): bypass EWMA adaptation in ImbalanceBarSampler — use fixed threshold

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) <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2026-05-09 21:41:22 +02:00
parent 7b6a2a63f8
commit 1aaf94306c

View File

@@ -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<OHLCVBar> = Vec::new();
for trade in &all_trades {