Skip to main content
Pro Feature. Requires a Pro or Ultra subscription. Get started at api.mathematicalcompany.com

Bars & Labeling

Horizon implements the full information-driven bar sampling and triple barrier labeling pipeline from Marcos Lopez de Prado’s Advances in Financial Machine Learning (Chapters 2-3). All functions run in Rust for maximum throughput on tick-level data.

7 Bar Types

Tick, volume, dollar, tick/volume imbalance, and tick/volume run bars. All Rust-native.

Triple Barrier

Profit-taking, stop-loss, and vertical barriers with volatility-scaled thresholds.

CUSUM Filter

Symmetric CUSUM for event-driven sampling of structural breaks.

Meta-Labels

Binary 0/1 labels for bet sizing on top of a primary directional model.

Information-Driven Bars

Standard time bars (1-minute, 5-minute) sample at fixed clock intervals, which over-samples quiet periods and under-samples volatile ones. Information-driven bars instead sample based on market activity, producing bars that carry roughly equal information content. Horizon provides three standard bar types and four information-driven bar types:

Tick Bars

Sample a new bar every threshold ticks.

Volume Bars

Sample a new bar when cumulative volume exceeds threshold.

Dollar Bars

Sample a new bar when cumulative dollar volume (price x volume) exceeds threshold.
All bar functions accept the same three input arrays: All three arrays must have the same length.

Bar Type

Every bar function returns list[Bar]. Each Bar object has the following fields:
If the last group of ticks does not fully meet the bar threshold, a partial bar is still emitted. This ensures no tick data is silently dropped.

Function Reference

Example: Comparing Bar Types


Triple Barrier Labeling

The triple barrier method (AFML Ch. 3) labels each trading event with the outcome of three competing barriers:
  1. Profit-taking (PT): upper barrier, price rises by a volatility-scaled amount
  2. Stop-loss (SL): lower barrier, price falls by a volatility-scaled amount
  3. Vertical barrier (VB): maximum holding period expires
Whichever barrier is touched first determines the label: +1 (profit-taking), -1 (stop-loss), or 0 (vertical barrier / insufficient return).

Step 1: Compute Daily Volatility

Returns a list the same length as prices. The first element is always 0.0 (no return available from a single price).

Step 2: CUSUM Filter for Structural Breaks

The symmetric CUSUM filter (AFML Ch. 2.5.2.1) produces a structurally meaningful subsample of the time series by detecting significant price moves and filtering out noise.
The filter tracks cumulative positive and negative sums of price changes. When either sum exceeds the threshold, the index is recorded and both sums reset.

Step 3: Apply Triple Barrier Labels

Barrier levels are computed in price space:
  • Upper: entry_price * (1 + daily_vol * pt_sl[0])
  • Lower: entry_price * (1 - daily_vol * pt_sl[1])

Step 4: Meta-Labels (Bet Sizing)

Meta-labeling (AFML Ch. 3.6) determines whether a primary model’s directional signals are correct. The primary model provides the direction (+1 long, -1 short), and the meta-label indicates if acting on that signal is profitable (1) or not (0).
Meta-labeling separates the problem into two models: a primary model for direction and a secondary model for bet sizing. The secondary model learns which of the primary model’s signals are worth acting on (label=1) vs. skipping (label=0). This is more robust than training a single model to do both.

Step 5: Drop Rare Labels

Remove label classes that appear less than a minimum percentage of the total. This prevents training classifiers on heavily imbalanced datasets.

BarrierLabel Type

Every label function returns list[BarrierLabel]. Each object has:

Full Pipeline Example

The events list must contain valid indices into the prices array. Out-of-bounds indices will raise a ValueError. When chaining cusum_filter output into triple_barrier_labels, both must reference the same price series.

Choosing Bar Types

Tick bars are the simplest non-time-based alternative. Each bar contains a fixed number of trades, so bars arrive faster during active periods and slower during quiet periods. Good baseline for comparison.
Volume bars normalize by trading volume, and dollar bars normalize by dollar volume. Dollar bars are preferred when price varies significantly over the sample period, as they keep the economic significance of each bar roughly constant.
Imbalance bars detect asymmetry in order flow. They produce more bars when one side (buy or sell) dominates, which often coincides with informed trading activity. Use these when order flow toxicity matters for your strategy.
Run bars detect sustained sequences of same-direction ticks. They are sensitive to persistent buying or selling pressure and produce more bars when the market trends strongly in one direction.