Back to Blog

Information Bars, Part 2: The Math Behind Imbalance Bars

ArcanaData EngineeringTrading

In Part 1, I explained why standard bars miss important market signals and introduced the concept of information-driven bars. Now let’s get into the actual mechanics. How does Arcana decide when to close a bar?

Buy or Sell?

Every trade that comes off the Coinbase exchange has a direction. Either a buyer initiated the trade (they hit the ask) or a seller initiated it (they hit the bid). In Arcana, I assign:

  • Buy = +1
  • Sell = -1

In practice, many exchanges don’t directly label trade direction. So I use what’s called the tick rule: if the current trade price is higher than the previous trade, it’s a buy. If it’s lower, it’s a sell. If it’s the same, carry forward the last classification. Simple, effective, and it’s what Prado recommends.

The Running Total

Once every trade has a direction, you keep a cumulative imbalance. A running total of those +1s and -1s:

Trade:     Buy   Buy   Sell  Buy   Sell  Sell  Buy
Direction: +1    +1    -1    +1    -1    -1    +1
Running:   +1    +2    +1    +2    +1     0    +1

When this running total gets big enough in either direction (positive or negative), you close the bar. That “big enough” is the threshold.

The cumulative imbalance walks up and down with each trade. When it hits the threshold, a bar is emitted.

The Adaptive Threshold

The threshold isn’t a fixed number. It adapts over time using an EWMA (Exponentially Weighted Moving Average). An EWMA is just a running average that cares more about recent values than old ones.

After each bar is emitted, the system updates two EWMA estimates:

  1. E[T], the expected number of trades in a bar (how long bars have been recently)
  2. E[b], the expected imbalance per trade (how directional the market has been)

The threshold for the next bar is:

threshold = E[T] × |E[b]|

If bars have been long (E[T] is high) and the market has been directional (|E[b]| is high), the threshold is high. It takes a bigger imbalance to trigger a bar. If bars have been short and the market balanced, the threshold drops. The system tunes itself.

The Three Flavors of Imbalance

The difference between TIB, VIB, and DIB is just what you’re counting:

TIB (Tick Imbalance): Each trade counts as +1 or -1. A whale buying 500 ETH counts the same as someone buying 0.01 ETH. Pure trade count.

VIB (Volume Imbalance): Each trade is weighted by its size. A 10 ETH buy contributes +10 to the running total, while a 0.01 ETH sell contributes -0.01. Big trades matter more.

DIB (Dollar Imbalance): Each trade is weighted by its dollar value (price times volume). A 10 ETH trade at $3,000/ETH contributes +$30,000. This naturally adjusts for price changes over time.

One property worth noting: if every trade were exactly 1 ETH at $1, then TIB = VIB = DIB. They only diverge when trade sizes and prices vary, which they always do in real markets.

Run Bars: The Cousin

Run bars (TRB, VRB, DRB) are the close relative. Instead of tracking the net imbalance, they track whichever side (buy or sell) has accumulated the most total.

Think of it this way. In imbalance bars, buys and sells cancel each other out. Five buys followed by five sells gives you a net imbalance of zero. In run bars, those same trades would show five on the buy side and five on the sell side, and the bar triggers when either side crosses the threshold.

Run bars ask: “Has one side gotten dominant enough?” rather than “Is there a net directional push?”

In practice, run bars tend to be less sensitive to the cancellation problem that plagues imbalance bars in balanced markets. This will become very relevant in Part 3.

How It All Connects in Arcana

When you run Arcana’s bar builder, the pipeline:

  1. Reads raw trades from the local data store
  2. Applies the tick rule to classify each trade as buy/sell
  3. Accumulates the running imbalance (or run totals)
  4. Checks against the adaptive threshold after each trade
  5. When the threshold is breached, emits a bar with OHLCV data
  6. Updates the EWMA estimates (E[T] and E[b])
  7. Resets the running total and starts the next bar

All of this is configurable in arcana.toml. You can set the EWMA window size, the target bars per day, and even override the E[T] constraints manually.

What Could Go Wrong?

At this point you might be thinking: self-tuning thresholds, adaptive resolution, what’s the catch?

When I ran this on six months of real ETH-USD data, the standard bars produced a clean 50 bars per day. The information-driven bars? TIB gave me 1.5 bars per day. VIB managed 6.8. The rest were similarly terrible.

The code was correct. Every formula matched the textbook exactly. The problem was deeper, and it lives in the math of random walks.