Information Bars, Part 4: Fixing Information Bars, Guardrails, Tuning, and Results
In Part 3, I explained the unstable equilibrium that was killing the information-driven bars. E[T] was drifting to infinity, thresholds were growing out of control, and TIB was producing 1.5 bars per day when it should have been producing around 50.
Time to fix it.
The Fix: Bowling Bumpers for E[T]
The solution is simple once you understand the problem: don’t let E[T] drift past guardrails.
Like bowling bumpers, I set a minimum and maximum that E[T] can’t exceed. After every bar, the system still updates its EWMA estimate normally. It’s still adaptive, still learning from the market. But then it clamps:
if e_t < minimum:
e_t = minimum # prevent collapse
if e_t > maximum:
e_t = maximum # prevent explosion
That’s it. The core algorithm stays exactly as Prado described it. I’m just preventing the feedback loop from running away.
This is exactly what the most popular open-source implementation of Prado’s work, mlfinlab by Hudson & Thames, does. They call the parameter exp_num_ticks_constraints. But their documentation doesn’t explain why it’s necessary. Now you know: it’s taming the quadratic scaling of random walks in balanced markets.
Auto-Calculated Guardrails
The guardrails are computed automatically from your target bar rate. If you want roughly 50 bars per day and your data has ~50,000 trades per day, the system calculates:
- Target E[T] = trades_per_day / bars_per_day
- Minimum = target times 0.2 (prevent collapse)
- Maximum = target times 5.0 (prevent explosion)
You can also override these manually in arcana.toml:
[bar.tib]
expected_ticks_constraints = [200, 5000]
I added guardrails to all six information bar types (TIB, VIB, DIB, TRB, VRB, DRB) and wrote 9 additional tests proving they work: collapse is prevented, explosion is prevented, and in trending markets where E[T] is naturally healthy, the guardrails never activate. They’re invisible when you don’t need them.
Problem A: EWMA Windows Were Too Large
Even with guardrails, two other settings were wrong.
The EWMA “window” controls how far back the running average looks. VIB had its window set to 200, meaning it averaged the last 200 bars. At 6.8 bars per day, that’s 29 days of history. The system was barely learning from new data. It was like driving a car while looking through a rearview mirror pointed at last month.
Fix: set all EWMA windows to 20. At ~50 bars per day, that’s about 2 days of lookback. Responsive enough to adapt to market regime changes without being whipsawed by every micro-fluctuation.
Before the fix, the windows were inconsistent across bar types: 20 for some, 200 for VIB, 40 for others. Now they’re all 20. Consistency matters when you’re comparing bars across types.
Problem B: Target Bars/Day Was Too Low
This one is a direct consequence of the quadratic random-walk penalty from Part 3.
Because of h-squared scaling, asking information bars for 50 bars/day doesn’t work. The math fights you. The adaptive threshold settles at a level that produces far fewer bars than the target due to the random walk dynamics. You need to overshoot the target so the actual output lands in the right range.
Fix:
- Imbalance bars (TIB, VIB, DIB): target = 300 bars/day, actual output: ~30-80 bars/day
- Run bars (TRB, VRB, DRB): target = 150 bars/day, actual output: ~30-60 bars/day
Run bars need less overcompensation because they don’t have the cancellation problem. In run bars, buys and sells accumulate separately instead of fighting each other. The random walk is less “drunk,” so the quadratic penalty is less severe.
The Final Scorecard
Everything I did, condensed:
- 68 mathematical proof tests, every formula matches Prado’s textbook exactly
- Discovered the unstable equilibrium, explains why TIB was at 1.5 bars/day
- Added E[T] guardrails, prevents both collapse and explosion
- Tuned EWMA windows to 20 (was 20/200/40, now consistent)
- Tuned bars_per_day targets (300 for imbalance, 150 for run)
- Added
expected_ticks_constraintsconfig, user-tunable in arcana.toml - 152 total tests passing (68 new proofs + 84 existing), 0 lint errors
What I Learned
The textbook gives you the formula. It doesn’t give you the failure modes.
Prado’s work is brilliant. The idea that bar resolution should adapt to information flow is fundamental and correct. But the implementation has a hidden assumption: that markets are directional enough to keep the feedback loop stable. In a liquid, balanced market like ETH-USD, that assumption breaks. The textbook doesn’t warn you. The reference implementation just silently includes guardrails without explaining why.
I think there’s a broader lesson here about the gap between academic research and production systems. The math can be perfect, all 68 of the proof tests confirm it. But “mathematically correct” and “practically useful” are different things. Understanding why something fails in production often requires a different kind of thinking than understanding how it’s supposed to work in theory.
Arcana’s information-driven bars are now producing healthy bar rates across all six types. The guardrails are doing their job. And the whole system is configurable enough that if your market behaves differently, more trending, less balanced, you can tune it.
The data pipeline is solid. Time to build on top of it.