Tick 失衡 Bar:用订单流失衡触发的自适应采样
tick/成交量/美元 Bar 共享一个盲区:只数活动的量,不看方向。1000 手买对轰 1000 手卖是均衡市场,2000 手连续买是知情交易——前三种 bar 一视同仁。Tick 失衡 Bar 把切分条件换成失衡量:逐笔方向 ±1 累加,失衡绝对值触阈值就切一根。12 万笔受控模拟(中段植入 p=0.68 持续买方失衡)实测:知情区段采样密度 30.2 vs 平静期 2.7 根/窗口,自动加密 11 倍;bar 长度中位数 1653→162 tick,bar 长度成了免费的知情强度指标;平方收益 ACF 从 0.335 压到 0.039,波动聚集被吸收进采样密度。代价:EWMA 阈值自举脆弱、bar 数不可预算、tick rule 误判在单边行情系统性放大。A 股:Level-2 BS 标志可跳过 tick rule,但 T+1 下 TIB 定位是特征时钟而非交易时钟(高阶)
一句话版本#
tick Bar / 成交量 Bar / 美元 Bar 只数活动的「量」,Tick 失衡 Bar 数活动的「方向差」——1000 手买对 1000 手卖是均衡,2000 手连续买是知情交易,前者该慢采样,后者该快采样。TIB 是信息驱动采样家族里第一个真正看懂「谁在买」的成员。
从「量的时钟」到「方向的时钟」#
前两篇我们沿着 AFML 的信息驱动采样家族走了两步:成交量时钟修好了「活动度量」(时间不是市场的时钟,交易活动才是),美元 Bar 修好了「时钟单位」(股数是名义单位,成交额才是经济单位)。
但这一家族的前三个成员——tick Bar、成交量 Bar、美元 Bar——共享一个盲区:它们是无方向的。
想象两段各 2000 笔的逐笔数据:
- 段 A:1000 笔买单和 1000 笔卖单犬牙交错,价格原地震荡;
- 段 B:2000 笔几乎全是买单,价格持续上行。
对成交量 Bar 来说这两段一模一样——累计量相同,切出的 bar 数相同。但对任何关心「市场里发生了什么」的人来说,这是两个完全不同的世界:段 A 是流动性提供者互相摩擦,段 B 大概率有知情交易者在持续吸筹。
Easley-O’Hara 的市场微观结构理论给出了理论支点:知情交易的签名不是活动量大,而是订单流失衡持续偏向一边。做市商正是靠监测失衡来推断自己是否在和知情者交易(这也是上一篇 VPIN 的核心逻辑)。既然失衡是信息到达的代理变量,为什么不直接用失衡来驱动采样时钟?
这就是 Tick 失衡 Bar(Tick Imbalance Bars, TIB)。
机制:失衡累计器#
TIB 的规则可以写在一张便签纸上。对每笔交易用 tick rule 打方向标签 (价格上跳判买、下跳判卖、无变化沿用上一笔),维护一个累计失衡:
当 超过阈值就切一根 bar,累计器清零,重新开始。
关键性质一眼可见:
- 买卖交错时, 正负抵消, 在零附近游走,bar 拉得很长;
- 单边失衡时, 线性积累,很快触阈值,bar 切得很密。
采样密度自动跟随「信息到达强度」,而不是跟随成交量或时间。
import numpy as np
def tick_imbalance_bars(b: np.ndarray, K: int = 60):
"""固定阈值版 TIB。b: 逐笔方向序列 (+1/-1),K: 失衡阈值。
返回每根 bar 的 (起点, 终点, tick数, 累计失衡)。"""
bars, theta, start = [], 0.0, 0
for i in range(len(b)):
theta += b[i]
if abs(theta) >= K:
bars.append((start, i, i - start + 1, theta))
theta, start = 0.0, i + 1
return barspythonAFML 原版比这更精巧:阈值不是固定的 ,而是 ,其中 (期望 bar 长度)和 (买单概率)都用 EWMA 从历史 bar 滚动估计。直觉是:如果市场本来就长期偏买(比如牛市),持续的轻度买方占优不算新闻,阈值会自动抬高;只有超出近期常态的失衡才触发切分。本文实验先用固定阈值版把机制看清楚,动态版的坑留到最后一节。
实验:植入一段知情交易,看谁能发现#
模拟 12 万笔逐笔数据,设计如下:
- 平静期:买卖概率各 50%,叠加 30% 的方向延续(模拟拆单——大单被切成同方向的一串小单),每笔价格噪声 σ=0.008;
- 知情期(第 5 万到第 7 万笔):买单概率抬到 68%,每笔波动放大到 σ=0.020——知情者带方向、带紧迫感进场;
- 每笔买卖方向额外贡献 0.002 的价格冲击,让失衡真实推动价格。
用固定阈值 K=60 跑 TIB,同时构造 bar 数完全对齐的等 tick Bar(每 710 笔切一根)做对照。
结果一:TIB 在知情区段自动加密 11 倍#

每 5000 tick 窗口内的切分次数:TIB 在知情区段平均 30.2 根/窗口,平静期只有 2.7 根/窗口——采样密度差 11 倍,而且加密的位置精确覆盖橙色的知情区段。等 tick Bar 的密度是一条死平的直线:每 710 笔切一根,管你市场里发生了什么。
这就是「方向的时钟」和「量的时钟」的本质区别。注意本实验中知情期的每笔波动也更大,但等 tick bar 加密不了——因为它数的是笔数,笔数没变。成交量 bar 在这里会稍好一点(知情期若伴随放量),但只要失衡是主要签名而放量不明显,它同样失明。
结果二:bar 长度分布暴露信息结构#

TIB 的 bar 长度中位数:知情期 162 tick,平静期 1653 tick,差一个数量级。bar 长度本身成了一个免费的信息指标——bar 越短,说明单位失衡积累越快,知情交易强度越高。有些实践者直接把「最近 N 根 TIB 的平均长度」当特征喂给模型,等于把 VPIN 的思想内嵌进了数据结构。
结果三:波动聚集被采样密度吸收#

bar 收益的统计性质对比(bar 数对齐,均为 169 根):
| 指标 | 等 tick Bar | Tick 失衡 Bar |
|---|---|---|
| 超额峰度 | 0.99 | 0.91 |
| 平方收益 ACF(1) | 0.335 | 0.039 |
| Jarque-Bera | 22.8 | 6.4 |
最陡峭的差异在平方收益自相关:等 tick Bar 高达 0.335(显著的波动聚集——知情期的高波动 bar 一根接一根),TIB 压到 0.039(接近零)。机制和成交量时钟消灭肥尾同构:知情期每根 TIB 覆盖的 tick 更少,单根 bar 的方差被拉回和平静期同一水平,波动的时变性被隔离进采样密度,收益序列本身回到近似同方差。对下游 ML 模型,这意味着少了「先识别波动区制」的作弊通道,特征-标签关系更平稳。
三个诚实的代价#
TIB 在 AFML 书里被排在采样方法的顶端,但工程上它是全家族最难伺候的成员。
1. 动态阈值的自举脆弱性。 AFML 版阈值依赖 和 的 EWMA 估计,而这两个量又依赖已切出的 bar——鸡生蛋问题。初始化参数选不好,前几百根 bar 的阈值会剧烈震荡,甚至陷入「bar 越切越短→期望长度估计越低→阈值越低→bar 更短」的正反馈。实践中要么用一段 burn-in 数据预热估计器(这段数据只校准不使用),要么给 设下限(如本文代码中的做法)。任何用全样本统计量校准阈值的做法都是前视偏差——这条红线与前两篇完全相同。
2. bar 数量不可预算。 时间 Bar 一年 252 根,成交量 Bar 大致可控,TIB 的产量完全由市场失衡结构决定——安静的年份可能只有几十根,动荡的月份可能上千根。多标的组合回测时各标的的 bar 完全不对齐,聚合逻辑要重新设计(通常做法:TIB 只做特征生成时钟,交易决策回到统一的时间网格)。
3. tick rule 误差的系统性放大。 上一篇说过 tick rule 准确率约 75%,且在单边行情中误判方向高度相关。TIB 恰恰在单边行情中最活跃——方向误判不再是白噪声,而是系统性偏置失衡读数。有 Level-2 真实买卖标志时(见下方 A 股注记),务必用真实标志替代 tick rule。
A 股落地注记#
- 数据优势再次兑现:A 股 Level-2 逐笔成交自带主动买卖(BS)标志,构造 TIB 可完全跳过 tick rule,失衡测量比美股 TAQ 数据更干净——这是上一篇 VPIN 之后第二个 A 股数据条件占优的场景。
- T+1 约束下的定位:TIB 切分不看时间,一天内可能切出几十根,但 T+1 使日内往返交易不可行。合理用法是把 TIB 当特征时钟(在失衡 bar 上计算特征、检测知情交易强度),交易执行仍落在日频网格上。
- 涨跌停的失衡假象:涨停封板时段成交极少但委买堆积如山,逐笔成交层面的失衡读数反而会「安静」下来——TIB 在此处欠采样。严谨做法是将触及涨跌停的时段单独标记,不让模型把封板误读为「无信息」。
下一篇预告:信息驱动采样解决了「怎么切 bar」,但 ML 管线还有一个上游问题——在哪些时点值得开一个样本。CUSUM 事件过滤器给出的答案是:只在市场偏离积累到足够大时才采样。