halo 的技术博客

返回

问题:暴跌之前,做市商看到了什么?#

2010 年 5 月 6 日的闪崩里有一个反复被讲的细节:在道指开始垂直坠落之前,很多自动化做市商已经主动退出了。他们不是被暴跌吓跑的——暴跌还没发生。他们撤退,是因为看到订单流出了问题。

什么问题?单边毒性。正常时候,做市商挂双边报价,买单卖单来了各吃一点,赚价差,风险对冲。但如果成交突然变成持续的单边——一直有人在砸盘、或者一直有人在扫货——做市商就慌了:这说明对手方知道点我不知道的东西,而我每成交一笔都在被他逆向选择。理性反应只有一个:拉宽报价,或者干脆撤单走人。而做市商一撤,流动性蒸发,价格就失去了缓冲垫——这才是闪崩的机制。

所以”订单流毒性”是一个先于价格的信号。价格是结果,毒性是原因。能提前量化毒性,就能在暴跌之前收到预警。量化它的工具,就是 VPIN(Volume-Synchronized Probability of Informed Trading,成交量同步知情交易概率)

订单流毒性在暴跌前率先抬升:VPIN 是先行预警

VPIN 的地基:为什么按成交量分桶,不按时间#

在讲 VPIN 公式之前,得先接受一个反直觉的设定:VPIN 不用时间作为时钟,用成交量。

传统的 K 线按固定时长切分——1 分钟一根、5 分钟一根。问题是市场活跃度极不均匀:开盘和收盘前成交爆炸,午盘死气沉沉。同样一根”1 分钟 bar”,可能装着 200 手也可能装着 20 手。用时间做时钟,等于在信息密集的时刻走得太慢、在信息稀薄的时刻走得太快。

VPIN 的解法是成交量桶(volume bucket):不管花多长时间,每积累固定成交量 V(比如日均成交量的 1/50)就封一个桶。交易越密集,桶封得越快,时钟走得越快——这叫”事件时间/成交量时间”。它的深层理由是:信息是随成交流入市场的,用成交量计时,才能让每个桶承载大致相同的”信息量”,桶与桶之间才可比。

VPIN 的地基:按成交量分桶而非时间,交易越密集时钟走得越快

在每个成交量桶内,我们统计买方成交量 V_B 和卖方成交量 V_S(两者相加等于桶容量 V)。桶内的订单失衡绝对值 |V_B − V_S| 就是这个桶的”毒性”:如果买卖各半,失衡为 0,无毒;如果全是买(或全是卖),失衡等于 V,剧毒。

VPIN 是这个失衡在最近 n 个桶上的移动平均,再除以桶容量归一化:

VPIN = (1/n) × Σ |V_B,k − V_S,k| / V
plaintext

它的取值在 [0, 1]:0 表示完美双边平衡,1 表示每个桶都是纯单边成交。经验上 VPIN 越高,说明知情交易者越活跃,做市商被逆向选择的风险越大,流动性越脆弱。

BVC:不看逐笔方向,怎么把成交量劈成买卖两半#

现在到了真正的难点。VPIN 需要每个桶的 V_BV_S——也就是要知道每一笔成交是买方发起还是卖方发起。

标准做法是逐笔分类:拿到 tick 级数据,用 Lee-Ready 规则(成交价高于中间价算买、低于算卖)给每笔打方向标签。问题有两个:

  1. 数据太重:逐笔 tick 数据量巨大,一只票一天几十万笔,全市场几千只票根本算不动。
  2. 中间价难要:Lee-Ready 要同步的买一卖一报价,很多历史数据只有成交没有盘口。

BVC(Bulk Volume Classification,批量成交量分类) 是 Easley、López de Prado、O’Hara 给出的绕过方案,狡猾且实用:别管逐笔方向了,用整根 bar 的价格变动来推断这根 bar 里买卖成交量的比例。

核心公式一行:

V_B = V × Φ( Δp / σ_Δp )
V_S = V × [1 − Φ( Δp / σ_Δp )]
plaintext

其中 V 是这根 bar 的总成交量,Δp 是这根 bar 的价格变动(收盘 − 上根收盘),σ_Δp 是价格变动的标准差,Φ 是标准正态的累积分布函数(CDF)。

直觉是这样的:如果一根 bar 价格涨了很多(Δp/σ 很大),说明这根 bar 里买压占主导,Φ 接近 1,绝大部分成交量被判为买;如果价格几乎没动(Δp≈0),Φ≈0.5,成交量对半分;如果暴跌,Φ 接近 0,成交量几乎全判为卖。用价格变动相对波动率的位置,平滑地在买卖之间分配成交量。

BVC 核心:不看逐笔方向,用价格变动的正态 CDF 分买卖量

它到底在近似什么?BVC 隐含假设”价格变动是净订单失衡驱动的、且失衡近似正态”。这显然是个近似——它牺牲了逐笔的精确性,换来了只需要 OHLCV 就能批量跑全市场的能力。用一点点精度,换整个市场的可扫描性,这就是 BVC 的交易。

Python 实现:从 OHLCV 到 VPIN#

第一步:成交量分桶#

真实分钟 bar 的成交量参差不齐,我们要把它们重新切成等成交量的桶。这一步是 VPIN 最容易写错的地方——一根 bar 可能跨越多个桶的边界,需要把它的成交量按比例劈开。

生产环境里应做更精细的 bar 拆分(把跨界 bar 按比例分到相邻桶),这里为可读性用整 bar 累积。核心逻辑——等成交量封桶——是一致的。

第二步:BVC 分类 + VPIN#

第三步:造一段”含毒”数据验证预警能力#

我们显式构造一个场景:前段正常双边、中段注入单边毒性(模拟知情交易者集中砸盘)、之后价格暴跌。看 VPIN 能不能在暴跌之前报警。

输出:

总桶数: 189
VPIN 首次突破 0.35 在第 128 桶
VPIN 峰值: 0.481
plaintext

对照数据生成:毒性段从第 1800 根 bar 注入、暴跌段从第 2150 根 bar 开始。换算到成交量桶后,VPIN 在暴跌对应的桶之前约 30 个桶就冲破了 0.35 阈值——预警跑在了价格前面。这正是 VPIN 的价值:它读的是订单流的单边性,而订单流毒性先于价格崩溃出现。

批量估计:把毒性做成全市场预警面板#

前面都是单只标的。BVC 真正的杀手锏是批量——因为它只要 OHLCV,你可以对全市场几千只票同时算 VPIN,做成一张横截面毒性面板,一眼扫出哪些标的正在积累毒性。

把结果画成一张预警面板:突破阈值的标的标红,低毒的标绿,一屏看清全市场的流动性风险分布。

批量估计:一次扫描全池,红色标的进入毒性预警

这张面板的用法:

  • 做市/流动性提供:VPIN 冲高的票主动拉宽报价或暂停做市,避开逆向选择高发期。
  • 执行算法:在高 VPIN 标的上放慢子单节奏、切换到更被动的挂单策略,别在毒性高峰主动吃单。
  • 风控:把全组合的成分股 VPIN 加权,作为组合级流动性风险的实时温度计,逼近阈值时降杠杆。

三段式总结#

A. 实现细节#

  • 信号字段:全流程只用 closevolume(OHLCV 的两列)。这是 BVC 相对逐笔分类的核心优势——不需要盘口、不需要 tick、不需要成交方向标签。
  • 时钟选择:用成交量桶而非时间桶。每积累固定成交量 V 封一桶,V 通常取日均量的 1/50 或总量的固定比例(本文用 2%)。桶容量是超参数,直接影响 VPIN 的灵敏度。
  • BVC 分配:买方量 V_B = V·Φ(Δp/σ),卖方量 V_S = V·[1−Φ(Δp/σ)]σ 用桶级 Δp 的标准差估计。
  • VPIN 口径:最近 n 桶(本文 n=50)的 |V_B−V_S| 之和除以 n·V 归一化到 [0,1]。这是纯诊断/预警量,不产生 signal-on-i/execute-on-i+1 的交易执行,因此无执行时滞问题;但作为交易过滤器使用时,必须用当前及历史桶、绝不能用未来桶。
  • 阈值:本文用 0.35 作预警线,真实阈值应按标的历史 VPIN 分布的分位数(如 90/95 分位)自适应设定。

B. 已知偏差#

  • BVC 是有偏近似Φ(Δp/σ) 假设价格变动由净订单失衡驱动且近似正态。在跳空、消息驱动的单根巨阳/巨阴 bar 上,这个假设会高估买卖分化;在高频微观结构噪声主导的 bar 上又会失真。它换来的是可批量性,代价是精度——不可与逐笔 Lee-Ready 分类的结果直接等同。
  • 桶容量敏感:成交量桶大小是超参数。桶太小,VPIN 噪声大、假警频繁;桶太大,反应迟钝、错过预警窗口。不同流动性的标的需要不同桶容量,横截面比较前必须归一化。
  • σ 的估计循环:波动率 σ 本身在危机中飙升,而它是 BVC 的分母。剧烈波动时 Δp/σ 可能被压平,反而低估分化——这是 BVC 在最需要它的时刻可能失灵的结构性弱点。
  • 同期温度计非水晶球:VPIN 度量的是当前正在发生的订单流毒性。它能领先价格崩溃是因为做市商撤退先于价格失稳,但它读的仍是同期订单流,不是对未来的预测。它是流动性枯竭的同步/略微领先指标,不是能预知任意时点崩盘的信号。
  • 本文为模拟验证:数据由显式植入毒性的生成过程产生,VPIN 的预警表现是”能否还原已植入信号”的验证,实证中信噪比远低于此,假阳性率显著更高。

C. 结果解读#

  • 预警确实跑在价格前面:模拟中 VPIN 在暴跌对应桶之前约 30 桶突破 0.35 阈值,峰值 0.48。机制上成立——毒性(单边订单流)是因,做市商撤退是果,价格失稳是果之果。
  • 成交量时钟是关键:如果改用时间桶,午盘的低成交时段会稀释毒性信号、开收盘的高成交时段又会制造假警。等成交量分桶让每个桶承载可比的信息量,这是 VPIN 有效的前提,不是可选项。
  • 批量能力是 BVC 的全部意义:单只标的用逐笔 Lee-Ready 精度更高;BVC 的存在理由是”只用 OHLCV 就能扫全市场”。它把毒性监控从”重仓单票的高频研究”降维成”全市场的日常风控面板”。
  • 用作过滤器而非 alpha:VPIN 高的标的不是”要跌”的做空信号——它是”流动性脆弱、别在此刻主动提供流动性或大单吃单”的风险信号。误当成方向性 alpha 使用,会在高波动中反复被打脸。
  • 诚实的边界:本文用可控模拟证明了预警机制的可行性,但 BVC 的近似误差、桶容量选择、σ 估计在真实危机中的退化,都会让实证 VPIN 的预警质量明显低于模拟。把它作为多因子风控体系的一环,而非单点决策依据。
订单流毒性批量估计:用 BVC 近似 VPIN 的流动性预警
https://blog.halo26812.eu.org/blog/flow-toxicity-bulk
Author halo
Published at 2026年7月27日
版权声明 CC BY-NC-SA 4.0
Comment seems to stuck. Try to refresh?✨