Bars¶
A bar summarises a run of consecutive trades: open, high, low, close, volume, VWAP, and the buy/sell split of its volume. What differs between bar types is only where the boundaries fall, so that decision is a rule and everything else is shared.
Five rules ship with the package:
| Rule | A new bar every… | Threshold |
|---|---|---|
time |
fixed span of the clock | a duration ("1min", pd.Timedelta) |
tick |
N trades | a trade count |
volume |
N units of traded size | an amount |
dollar |
N units of price × size | an amount |
imbalance |
N units of drift in signed size | an amount |
The last four sample the market by activity rather than by the clock. That is why the quant literature prefers them: a quiet hour and a busy minute produce the same number of bars, so bar returns come much closer to being independent and identically distributed.
See the "Build bars from trades" how-to for a worked example, and Extending for writing a rule of your own.
Functions¶
bars ¶
bars(
trades: DataFrame,
rule: str = "time",
threshold: Any = None,
*,
target_bars: int = 50,
sign_method: str | None = None,
quotes: DataFrame | None = None,
) -> pd.DataFrame
Resample trades into bars.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
trades
|
DataFrame
|
Trades with at least |
required |
rule
|
str
|
Registered rule name: |
'time'
|
threshold
|
optional
|
How much of the rule's own quantity closes a bar: a duration for
|
None
|
target_bars
|
int
|
How many bars the default threshold aims at. Ignored when threshold is given. |
50
|
sign_method
|
str or None
|
How to classify the aggressor side: |
None
|
quotes
|
DataFrame
|
Book snapshots for the Lee–Ready classifier — a frame with
|
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
One row per bar, in time order, with the columns in
:data:
Every bar holds at least one trade: a clock span in which nothing
traded produces no row. The last bar is whatever trades were left
over, so it may not have reached the threshold; drop it with
The frame's |
Raises:
| Type | Description |
|---|---|
ConfigError
|
If required columns are missing, or the threshold does not suit the rule. |
KeyError
|
If rule is not registered; the message lists the registered names. |
ObAnalyticsError
|
If trades is empty. |
Notes
Prices and sizes pass through in the units they arrive in. A pipeline
result holds prices as whole ticks and sizes as whole lots, so a
"dollar" threshold there is in ticks × lots, not in the quote
currency. Convert the frame first (see
:func:~ob_analytics.visualization.display_result) to work in quote-
currency amounts.
Examples:
register_bar_rule ¶
Register rule under its own :attr:~ob_analytics.protocols.BarRule.name.
Case-insensitive; overwriting an existing registration is allowed, so a rule of your own may deliberately shadow a built-in one.
get_bar_rule ¶
Return the bar rule registered under name (case-insensitive).
Raises:
| Type | Description |
|---|---|
KeyError
|
If no rule is registered under name; the message lists the registered names. |
The built-in rules¶
ClockRule ¶
A new bar every fixed span of the clock — classic OHLCV.
The threshold is a fixed duration: a string pandas reads as one
("5s", "1min", "1h") or a :class:pandas.Timedelta. A
calendar step with no fixed length (a month, a business day) is not a
duration and is rejected.
Bars are aligned to the epoch, so "1min" cuts on the minute whatever
the first trade's timestamp. A span in which nothing traded produces no
bar: every row :func:bars returns holds at least one trade.
TickRule ¶
A new bar every N trades, whatever their size.
The threshold is that count. "Tick" here is the market-data sense of one printed trade, not the price increment.
AccumulationRule
dataclass
¶
A new bar every N units of some quantity the trades carry.
One shape covers the three activity rules; they differ only in what they accumulate and in whether that quantity is signed:
"volume"— traded size."dollar"— price × size, in the units of the input frame."imbalance"— signed size,+for buyer-initiated trades and-for seller-initiated ones.
An unsigned rule closes a bar when the running total reaches the threshold. A signed rule closes one when the running total reaches the threshold in either direction, so a bar ends on a burst of one-sided flow and a balanced stretch of trading stays inside one bar.
The threshold is fixed, not the moving estimate of López de Prado's original imbalance bars: a fixed threshold gives the same bars every time the same trades are read, which is what makes a bar table reproducible.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Registered rule name. |
quantity |
Callable
|
Maps the normalized trade frame to the per-trade amount accumulated. |
signed |
bool
|
Whether that amount carries the aggressor's sign. |
default_threshold ¶
Return the threshold that cuts frame into about target_bars bars.
An unsigned quantity simply splits its total target_bars ways. A signed one part-cancels, so its total says nothing about how far it drifts: the running sum wanders like a random walk, whose distance after a share of the trades is the root of that share's squared amounts.
assign ¶
Return the bar index of each trade by accumulating up to threshold.