Practitioner synthesis. Changing the sampling clock changes the statistics of a return series, not the information available to trade on. Activity-based bars give you returns that are closer to Gaussian and models that fit better. Every one of those improvements is measured at the bar close, and a live order cannot fill at the bar close. This guide covers the formal sampling rules, the traps in calibrating them, and the arithmetic between a cleaner in-sample series and a tradeable edge.
Definition. A bar is a summary (open, high, low, close, volume, trade count, notional) of every trade between two closing times \(T_{k-1} < t_i \le T_k\). A sampling rule decides when \(T_k\) arrives. Time bars close on the wall clock. Information-driven bars close once some measure of market activity has accumulated: trades, shares, notional, signed volume, or one-sided aggression. Picking the rule is a modelling decision, and it should match the job the bars are for: volatility estimation, feature engineering, execution scheduling, or event detection.
Why the wall clock is the wrong clock
The cleanest argument is the old subordination idea (Clark 1973; Ané and Geman 2000). Model a time bar’s return as the sum of \(N_k\) trade-level increments, each with variance \(\sigma^2\), where \(N_k\) is the random number of trades that happened to land in that minute. Even if the increments were perfectly Gaussian, the bar return would be a variance mixture:
$$ r_k \mid N_k \sim \mathcal{N}\!\left(0,\; N_k \sigma^2\right) \quad\Longrightarrow\quad \operatorname{Kurt}(r_k) \;=\; \frac{3\,\mathbb{E}[N_k^2]}{\mathbb{E}[N_k]^2} \;=\; 3\left(1 + \mathrm{CV}^2(N_k)\right). $$The excess kurtosis of time-bar returns is therefore at least \(3\,\mathrm{CV}^2(N_k)\), where CV is the coefficient of variation of trades per bar. An intraday U-shape, news bursts and volatility clustering easily push CV above 1 for one-minute bars on liquid names. That gives a kurtosis of 6 or more before any genuinely fat-tailed price move is involved. The same mixture produces heteroskedasticity: a bar’s variance is set by how busy that minute was. Fix \(N_k\) and this channel disappears. That is the whole statistical case for tick bars, and versions of it hold for volume and notional clocks. It is also why realized-variance estimators sampled in intrinsic time can be more efficient than calendar-time sampling, and why time-subordinated Brownian motion remains a live modelling line.
The operational version: 390 one-minute bars give the lunchtime minute with 200 trades the same regression weight as the opening minute with 5,000. A model fit on time bars spends most of its sample on periods where nothing happened. Meanwhile the minutes where order flow was informative (opens, data releases, liquidation cascades) get squeezed into a handful of rows whose closes hide everything that happened inside them.
The sampling rules, formally
Common notation: the trade stream is \(\{(t_i, p_i, v_i)\}\). The aggressor sign \(b_i \in \{-1, +1\}\) comes from the venue’s aggressor flag where one exists. Otherwise it comes from the tick rule (\(b_i = \operatorname{sgn}(\Delta p_i)\), carrying \(b_{i-1}\) forward when \(\Delta p_i = 0\)) or from Lee–Ready against the prevailing quote. A bar closes at the first trade where its accumulator crosses its threshold, and the accumulator then resets.
Tick bars. The accumulator counts trades, \(S_k = \sum 1\), and closes at \(S_k \ge L_{\text{ticks}}\). This equalizes decisions only if one trade is one decision, which is false on most modern venues (see the mechanical channel below).
Volume bars. \(S_k = \sum v_i \ge L_{\text{vol}}\). This equalizes shares or contracts traded, which is the clock that VWAP schedules and the volume-synchronized literature (Easley, López de Prado and O’Hara’s “volume clock”) run on.
Dollar bars. \(S_k = \sum p_i v_i \ge L_{\text{notional}}\). Notional is robust to large price-level changes, splits and share issuance, which matters for multi-year samples. It is the sensible default for crypto, where a coin can move 10× within a sample.
Delta bars. These close when cumulative signed volume crosses a fixed level, \(\lvert\sum b_i v_i\rvert \ge \Delta_0\). They are a fixed-threshold precursor to imbalance bars: simple, interpretable, and blind to whether that level of imbalance is unusual today.
Imbalance bars (TIB / VIB / DIB). Let \(\theta_T = \sum_{t=1}^{T} b_t v_t\), where \(v_t = 1\) gives tick imbalance, \(v_t\) = shares gives volume imbalance and \(v_t = p_t v_t\) gives dollar imbalance. The bar closes when realized imbalance exceeds what is expected for a bar of typical length:
$$ T^{*} = \min\Big\{\, T \;:\; \lvert\theta_T\rvert \;\ge\; \mathbb{E}_0[T]\,\cdot\,\big\lvert 2\,\mathbb{P}_0(b_t = 1) - 1 \big\rvert\,\cdot\,\mathbb{E}_0[v_t] \Big\}. $$The three expectations are usually exponentially weighted moving averages over past bars and ticks. The rule is a surprise detector: a bar closes early when one side is aggressing harder than the recent base rate.
Run bars. The “run” in López de Prado’s definition is the cumulative one-sided volume inside the bar, not a streak of consecutive same-sign trades:
$$ \theta_T = \max\Big\{ \sum_{t \le T:\, b_t = 1} v_t,\; \sum_{t \le T:\, b_t = -1} v_t \Big\}, \qquad T^{*} = \min\Big\{ T : \theta_T \ge \mathbb{E}_0[T]\cdot\max\{\mathbb{P}_0^{+}\,\bar v^{+},\; \mathbb{P}_0^{-}\,\bar v^{-}\}\Big\}. $$Here \(\mathbb{P}_0^{\pm}\) is the probability of a buy or sell and \(\bar v^{\pm}\) the expected size conditional on side. Unlike imbalance, a run does not cancel when the other side trades, so run bars respond to sustained one-sided participation (a working meta-order) even while the opposite side keeps printing. Several open-source libraries implement the consecutive-streak version under the same name. Check which one yours computes, because the two produce different bars and different statistics.
Quantile bars. These replace the EWMA expectation with an empirical quantile of a trailing window: close when the accumulator exceeds the \(q\)-th quantile of its value over the last \(W\) completed bars. They are less elegant and more stable, and the trade-off between the window \(W\) and responsiveness is explicit instead of hidden inside an EWMA span.
| Bar | Accumulator | What it equalizes | Typical failure |
|---|---|---|---|
| Time | elapsed seconds | wall-clock exposure | variance mixture → fat tails, heteroskedasticity |
| Tick | trade count | prints | matching-engine fragmentation inflates counts |
| Volume | shares or contracts | participation | price-level drift across years |
| Dollar | notional | capital exchanged | auction prints blow through thresholds |
| Delta | signed volume, fixed level | net aggression | static level goes stale across regimes |
| TIB / VIB / DIB | signed flow vs EWMA expectation | surprise in aggression | threshold explosion or collapse |
| Run | one-sided cumulative flow | sustained participation | definition ambiguity; slow in two-sided markets |
| Quantile | any, vs trailing quantile | relative activity | window choice; non-stationary bar counts |
Two channels: mechanical and informational
A bar series improves for two different reasons, and only one of them carries economic content.
The mechanical channel. Most of the gain from tick, volume and dollar bars is a normalization. They divide out the intraday activity cycle and volatility clustering, so the resulting returns look closer to i.i.d. Gaussian. Part of the measured imbalance is mechanical too. Under the tick rule, bid–ask bounce alone generates alternating signs, so \(\theta_T\) contains spread noise in proportion to how often the price oscillates between bid and ask. On large-tick instruments, depleting the queue at one price level produces a burst of same-sign prints whose “imbalance” mostly reflects queue length. Fragmentation adds another distortion: on most crypto venues a single market order that walks five price levels prints as dozens of trades, one per resting maker order. A tick bar then counts the matching engine’s bookkeeping, not decisions. Before building tick or tick-imbalance bars on such venues, aggregate prints that share an aggressor order ID or an exchange timestamp.
The informational channel. Imbalance and run bars close early when aggression is one-sided beyond its base rate. That is roughly the signature of informed traders splitting meta-orders, liquidations, and toxic flow in general. On this channel the bar close is an event, and the most useful way to treat these bars is as event triggers, not as a resampled dataset. “Sample a label whenever a DIB closes” is a well-posed event study. “Run a GARCH on DIB returns” mixes the trigger into the series being modelled. The informational content they target is the same object studied in the LOB-imbalance literature and the order-flow intensity models, measured with a coarser clock.
Calibration and look-ahead traps
1. The EWMA threshold has an unstable fixed point. Take the imbalance rule under balanced flow: signs close to coin flips and an estimated bias \(\delta = \lvert 2\hat{\mathbb{P}}(b=1) - 1\rvert\) that is small. A symmetric random walk needs about \(h^2\) steps (in units of trade size) to first reach \(\pm h\). With \(h = \mathbb{E}[T]\,\delta\), the next bar’s length is roughly \(T_{k} \approx (\mathbb{E}[T]\,\delta)^2\), and the EWMA feeds it back into \(\mathbb{E}[T]\). The map has a fixed point at \(\mathbb{E}[T]^{*} = 1/\delta^{2}\), and it is unstable. Start above it and bars lengthen without bound. Start below it and they collapse toward one-trade bars. Which way a backtest goes depends on the warm-up guess, and that is the “bars explode on day three” behaviour practitioners report. The analysis is stylized (\(\delta\) is itself re-estimated), but the instability is real. Fixes: anchor \(\mathbb{E}[T]\) to a fixed budget and adapt only \(\delta\) and \(\mathbb{E}[v]\); clamp \(\mathbb{E}[T]\) to \([T_{\min}, T_{\max}]\); or switch to quantile thresholds.
2. Halts and auctions break volume and notional clocks. An opening or closing auction prints one trade carrying a large share of the day’s volume. A dollar-bar threshold set as a fraction of daily notional is blown through by a single print, which yields either one enormous bar or many zero-duration bars sharing one timestamp, depending on whether the implementation splits prints. After a volatility halt the EWMA still holds the pre-halt regime, so the first post-halt bars are mis-sized in whichever direction the halt moved activity. Route auction prints to their own bar type, and reset or freeze the EWMA state across halts.
3. Thresholds set from the full sample are look-ahead. “Dollar bars at 1/50 of average daily notional” is a full-sample statistic unless the average is trailing. In a trending-volume market such as crypto 2020–2021, a full-sample threshold produces too few bars early and too many late. The returns look stationary because the clock was tuned with knowledge of the future.
4. The bar timestamp is not the decision time. A bar closes on the trade that crosses the threshold, and you learn about that trade after feed latency. Features stamped at \(T_k\) are fine. Entries at \(p_{\text{close},k}\) are not: they are same-bar execution in a new costume. Using the bar’s VWAP as the entry price is worse, because it averages trades that happened before the signal existed.
5. Asynchronous closes poison cross-asset joins. Volume bars on two assets never close together. Joining their features on bar index \(k\) is look-ahead whenever asset B’s \(k\)-th bar closed after asset A’s. The correct join is an as-of join on timestamps (each row sees only B’s last completed bar). Even done correctly, non-synchronous sampling biases correlations toward zero at short horizons (the Epps effect) and can manufacture lead–lag relationships out of sampling alone. Interpolation-free estimators for asynchronous tick data exist and are worth using before believing a cross-asset signal built on activity bars.
6. Exchange time versus receive time. Activity clocks amplify timestamp errors. A burst of prints with identical exchange timestamps but different receive times can be ordered differently by two pipelines, which changes which trade closes the bar and what the bar’s features are. Pick one timestamp, sort stably, and store both.
The monetization gap: fee-wall arithmetic
Information-driven bars reliably improve three in-sample diagnostics: returns closer to Gaussian, lower heteroskedasticity, and, for imbalance and run bars, higher serial correlation of bar returns. The first two are the mechanical normalization above, and they are real. The third is partly constructed. A bar that closes because one-sided aggression accumulated tends to be followed by continuation (meta-orders keep working) and also by bounce at the close print. Neither is guaranteed to survive being measured at your fill price instead of the last trade.
Now the fee wall. Suppose a feature built on dollar-imbalance bars predicts the sign of the next bar’s return with directional accuracy \(p\), and the next bar’s mean absolute return is \(\mathbb{E}\lvert r_\tau\rvert\). The gross edge per round trip from trading the sign is \((2p-1)\,\mathbb{E}\lvert r_\tau\rvert\), so break-even against a round-trip cost \(C_{\text{rt}}\) requires
$$ p^{*} \;=\; \tfrac{1}{2} \;+\; \frac{C_{\text{rt}}}{2\,\mathbb{E}\lvert r_\tau\rvert}. $$Use crypto-perp numbers that are typical for a non-VIP taker in late 2026: 2 × 2.5 bps fees, 1 bp of quoted spread, and 1.5 bps of extra slippage from arriving just after a sweep. That gives \(C_{\text{rt}} = 7.5\) bps. With short bars where \(\mathbb{E}\lvert r_\tau\rvert = 8\) bps, the break-even accuracy is \(p^{*} = 0.5 + 7.5/16 \approx 0.97\). With bars four times longer (\(\mathbb{E}\lvert r_\tau\rvert = 20\) bps) it is still \(0.69\). The published “58% accuracy on imbalance bars” result fails this check by a factor of several.
Stated as \(R^2\): a linear forecast with correlation \(\rho\) to the next return, traded on its sign, earns about \(\rho\,\sigma_\tau\sqrt{2/\pi}\) per trade gross. An excellent-sounding out-of-sample \(R^2 = 2\%\) (\(\rho \approx 0.14\)) on bars with \(\sigma_\tau = 10\) bps earns about \(0.14 \times 10 \times 0.80 \approx 1.1\) bps per trade, roughly a seventh of the 7.5 bps cost. Statistical and economic significance part ways at exactly this point. Run your own horizon and cost assumptions through the transaction-cost break-even calculator before reading anything else in a paper’s results table.
The conditional cost is worse than the unconditional one, and that is the part specific to activity bars. Imbalance-bar closes cluster where liquidity is thinnest. By construction they fire when a one-sided sweep has just completed: the swept side of the book is depleted, quoters have widened or pulled, and every other participant watching the same flow fires at the same moment. Your average spread over the day might be 1 bp. Your spread conditional on a DIB close is the post-sweep spread, often a multiple of that. Market-maker adverse-selection mechanics predict it: the moment your signal fires is the moment the passive side is pricing in the most toxicity. Execution as a maker does not escape it either. Resting at the bar close, you fill only when the continuation fails, which is adverse selection in its purest form. A backtest that charges average costs to trades triggered at bar closes understates costs most where its signal is strongest.
Two smaller accounting traps compound this. Bar counts per day vary, so annualizing a Sharpe ratio as \(\sqrt{\text{bars per year}}\) times the per-bar Sharpe is wrong whenever activity trends. Annualize in calendar time from daily P&L. And a falsification study that applies honest constraints to OHLCV-based intraday signals finds the edge that survives costs is far smaller than the in-sample statistics suggest. That is the expected outcome here, not a surprise.
Which clock for which job
- Volatility and covariance estimation: tick or volume time, with noise-robust estimators. This is where activity clocks earn their keep.
- Daily or slower cross-sectional features: time bars are fine. The variance-mixture problem averages out at daily aggregation, and the joins are simpler.
- Execution scheduling: volume time, because that is what participation-rate and VWAP algorithms actually track.
- Short-horizon event detection: imbalance or run bars as triggers, labelled with costed forward returns measured from realistic fill times.
- Intraday ML datasets: dollar bars with trailing thresholds, as-of joins, and calendar-time evaluation. Benchmark against time bars over the same horizon. If the activity clock’s advantage disappears once costs are charged, the advantage was the mechanical channel.
Production failure modes
- Live bars disagree with backtest bars. Live feeds drop, duplicate and reorder prints, so the live bar sequence diverges from the cleaned historical one within hours. Any feature that depends on which trade closed the bar is not reproducible live. Replay the recorded live feed through the research code and diff the bars weekly.
- Threshold drift without alerts. A trailing-notional threshold quietly halves after a volume regime change, the bar count doubles, and every per-bar feature changes scale. Monitor bars per day as a first-class metric.
- Silent auction contamination. One unfiltered closing-auction print creates a bar whose “return” is the auction imbalance. Filter by sale condition codes.
- Venue fragmentation. Single-venue dollar bars on an asset that trades on twelve venues sample one venue’s share of flow, and that share moves with fee schedules.
- The signal fires with everyone else’s. Imbalance-bar logic is public and widely implemented. Live fills at the trigger show the crowding directly, as markouts worse than the backtest’s assumed cost.
Questions to ask a paper (or backtest)
- Which clock, and were its thresholds set with trailing or full-sample statistics?
- How are trade signs obtained (aggressor flag, tick rule, Lee–Ready), and were fragmented prints aggregated?
- Is the entry price the bar close, the next trade, or a simulated fill after latency?
- What are the round-trip cost and \(\mathbb{E}\lvert r_\tau\rvert\) at the prediction horizon, and does the claimed accuracy clear \(p^{*}\)?
- Is the comparison against time bars run at the same calendar horizon, with the same costs?
- For multi-asset features: as-of joins on timestamps, or joins on bar index?
- Are the reported normality or autocorrelation improvements used as evidence of tradeable information? They are evidence of a better clock and nothing more.
What our scoring captures
Papers that resample to activity bars score on our empirical-rigor axis mostly according to what they do after resampling: costed evaluation from realistic fill times, trailing calibration, and an honest time-bar baseline. “Dollar bars improve normality” is a property of the clock and earns little. “A DIB-triggered signal survives 2× costs out of sample” is a result, and it is rare. The broader literature on order-flow clocks sits in the market microstructure and econometrics & time series hubs.
Run your numbers: transaction-cost break-even calculator → · tick-data storage sizer → · The data underneath: market data types → · storing tick data → · What the bars are detecting: order-flow intensity and Hawkes processes → · LOB imbalance → · The field: LOB research map →
Background: the classic references are Clark (1973), Ané and Geman (2000), Easley, López de Prado and O’Hara (2012) on the volume clock, and López de Prado (2018, ch. 2) for the imbalance and run bar definitions. Practitioner treatments that informed this synthesis include Trading the Breaking and HangukQuant Research. Browse the flowchart library, the rest of the guides, and the tools.