VPIN 知情交易概率:用成交量桶量化逆向选择风险
VPIN 被当作「知情交易探测器」用,但它只看订单流失衡的绝对值——而失衡有两个来源:真正的知情交易,和纯粹想快点成交的大额委托。受控三状态模拟(12 万根 bar、4995 个成交量桶,两种来源的真值都已知)给出决定性读数:VPIN 与「总不平衡流量」相关 0.996,与真实知情占比只有 0.347,与无知情大额委托反而有 0.648。构造一个零知情的世界(只有大额委托),VPIN 均值 0.152 仍是真实市场 0.153 的 99%——这个指标在完全没有信息不对称时读数几乎不变。后果直接体现在钱上:95 分位报警的假发现率 85.1%,99 分位精确率归零;同一条前 10% 警报内部,知情主导的桶做市亏 35.4bp,大额委托主导的桶反而赚 7.96bp(t=4.14),而后者占警报的 76%——高 VPIN 时段整体做市 P&L 是 −2.29bp,比安静时段的 −9.07bp 还好。八项对抗式检验含两个推翻常识的结果:BVC 分类误差几乎不损失相关性(0.354 对 0.347),公平匹配窗口后钟表时间桶反而略胜体积时钟(0.451 对 0.347)。混合比例扫描给出边界——无知情委托占比从 0 升到 22%,与知情的相关性从 0.998 塌到 0.196,而与总流量的相关性始终锁在 0.996 以上(高阶)
问题:VPIN 到底在测什么#
做市商的核心恐惧不是波动,是逆向选择——你挂的限价单被一个比你知道得多的人吃掉了。价格随后朝着对你不利的方向走,你的库存变成亏损。
VPIN(Volume-Synchronised Probability of Informed Trading)是 Easley、López de Prado 和 O’Hara 提出的实时度量。它的计算极其简单:
把成交按固定成交量切成桶(不是固定时间),每个桶算买量减卖量的绝对值,再对最近 个桶取平均。
思路很直观:知情交易者是单边的——他知道价格要涨,就一路买。所以订单流失衡越大,知情交易的成分越高。
但这个推理里有一个洞。 单边扫货的不只有知情者。一个养老金要在今天调仓 5 亿,一个 ETF 要跟踪指数变更,一个 CTA 触发了止损——这些委托同样是单边的、同样制造巨大的失衡,但它们不携带任何关于未来价格的信息。
这个式子分不清这两者。本文用一个真值已知的受控模拟,量化这个混淆到底有多严重。
模拟设计:让「知情」和「大额但无知情」都可观测#
关键是构造一个三状态市场,其中两种失衡来源的差别只体现在价格的后续行为上:
- 状态 0:均衡噪声交易,买卖各半
- 状态 1:知情交易——单边流量 + 永久价格漂移(信息被吸收进价格,不回补)
- 状态 2:无知情大额委托——单边流量 + 暂时价格冲击(做市商补库存后价格回归)
def simulate_market(rng, n=N_BARS, p_info=0.10, p_meta=0.14,
imb_info=0.70, imb_meta=0.70, # 两者失衡程度故意设成一样
volm_info=2.2, volm_meta=2.4,
drift_info=2.0, drift_meta=1.7, revert=0.85):
...
# 永久成分:只有知情交易贡献
perm = rng.normal(0, SIG, n) + (state == 1) * direc * drift_info * 1e-4
# 暂时成分:大额委托推动价格,然后指数回补
trans_push = (state == 2) * direc * drift_meta * 1e-4
transient = np.zeros(n); acc = 0.0
decay = 1.0 - 1.0 / 45.0
for t in range(n):
acc = acc * decay + trans_push[t]
transient[t] = acc * revert
logp = np.cumsum(perm) + transientpython注意 imb_info 和 imb_meta 都设成 0.70。 这是故意的:两种状态制造的订单流失衡在统计上无法区分,唯一的差别是价格后来回不回补。这正是真实市场的处境——你在事发当时看到的东西是一样的。
成交量分桶要在 bar 边界处做插值,否则桶大小会随机漂移:
def volume_buckets(vol, buy, sell, state, direc, logp, bucket_v=3000.0):
"""等成交量分桶(体积时钟),在边界处劈开 bar。"""
cb = np.cumsum(vol)
edges = np.arange(1, int(cb[-1] // bucket_v) + 1) * bucket_v
idx = np.searchsorted(cb, edges)
def interp(c, k, e):
pc = cb[k-1] if k > 0 else 0.0
px = c[k-1] if k > 0 else 0.0
return px + (e - pc) * (c[k] - px) / (cb[k] - pc) # 线性劈分
...python12 万根 1 分钟 bar,切出 4995 个成交量桶,滚动窗口 50 桶。知情 bar 占 8.47%,无知情大额委托占 10.39%。
核心结论:VPIN 测的是「有人在单边扫货」#

三个相关系数说完了整篇文章:
| VPIN 与什么相关 | 相关系数 |
|---|---|
| 总不平衡流量(知情 + 大额委托) | 0.996 |
| 无知情大额委托占比 | 0.648 |
| 真实知情成交占比 | 0.347 |
VPIN 几乎完美地测量了「有人在单边扫货」(0.996),但对「那个人是否知道什么」只有微弱的辨别力(0.347)。 而且它和无知情委托的相关性(0.648)接近知情的两倍——纯粹因为在我的设定里后者更频繁。

上图是可观测的 VPIN,下图把两个真实驱动拆开(向上是知情,向下是无知情大额委托)。VPIN 的每一个尖峰,你都无法从曲线本身判断它来自哪一侧。
零知情的世界里,VPIN 读数几乎不变#
最直接的检验:构造一个完全没有知情交易的市场(p_info = 0),只保留大额委托。

| 市场 | VPIN 均值 |
|---|---|
| 真实市场(知情 + 大额委托) | 0.153 |
| 只有大额委托,知情真值 = 0 | 0.152 |
| 纯噪声安慰剂 | 0.024 |
知情交易从 8.47% 降到 0,VPIN 只从 0.153 掉到 0.152——变化 1%。
如果 VPIN 是「知情交易概率」,这个数字应该崩塌。它没有。它测的是流量结构,不是信息含量。
中间那张图是另一个陷阱:机械地板。因为公式里有绝对值,即使买卖完全随机, 恒成立。纯噪声数据上 VPIN 均值是 0.024,而且桶越小地板越高(桶 500 时 0.056,桶 30000 时 0.008)——这纯粹是 的统计涨落被 除出来的结果。跨品种、跨桶大小比较 VPIN 绝对值是没有意义的,除非先减掉各自的零假设基线。
报警器的真实成色:85% 假发现率#

左图:VPIN 十分位确实单调——但两条线一起涨。最高分位相对最低分位,知情占比提升 2.99 倍,无知情大额委托提升 9.03 倍。VPIN 对后者的富集能力是前者的三倍。
右图是报警质量。定义两种「事件」:
| 报警阈值 | 精确率(任何不平衡流) | 精确率(真的有知情交易) | 假发现率 |
|---|---|---|---|
| 80 分位 | 100% | 24.5% | 75.5% |
| 90 分位 | 100% | 21.6% | 78.4% |
| 95 分位 | 100% | 14.9% | 85.1% |
| 99 分位 | 100% | 0.0% | 100% |
抓「有人在单边扫货」百发百中,抓「有知情交易」的假发现率 85%。 而 99 分位——最极端的报警——精确率是 0。
最极端的 VPIN 读数完全不来自知情交易,它们来自最大的那些无知情委托。这在事后看很合理:一个 5 亿的指数调仓单,制造的失衡比任何知情者都大,因为知情者要藏。
钱的维度:高 VPIN 时做市反而更安全#
前面都是统计。做市商真正关心的是 P&L。模拟一个被动做市商:接下净流量的反向,持有 分钟后按市价结算。

| 评估窗口 | 全样本 | VPIN 后 50% | VPIN 前 10% |
|---|---|---|---|
| 30 分钟 | −7.18bp (t=−9.85) | −5.93bp | −6.64bp |
| 120 分钟 | −7.55bp (t=−4.80) | −9.07bp | −2.29bp |
| 480 分钟 | −0.12bp | −14.38bp | +29.11bp |
逆向选择是真实的:全样本被动做市在 30 分钟窗口亏 7.18bp,t 统计量 −9.85,毫无疑问。
但 VPIN 报警时反而亏得更少。 120 分钟窗口,安静时段亏 9.07bp,报警时段只亏 2.29bp。480 分钟时报警时段甚至赚 29.11bp。
右图解释了为什么。把同一条「前 10%」警报按主导来源拆开:
| 警报内部构成 | 占比 | 120 分钟做市 P&L |
|---|---|---|
| 知情主导 | 24% (n=117) | −35.40bp |
| 大额委托主导 | 76% (n=378) | +7.96bp |
t = 4.14,差异高度显著。
知情主导的警报确实是灾难(亏 35.4bp),但它们只占警报的四分之一。 剩下四分之三是无知情的大额委托——给它们提供流动性是赚钱的,因为价格会回补,做市商赚的正是这个回补。
这两类被平均之后,整条警报线看起来「无害」甚至「有利」。一个照着 VPIN 撤单的做市商,会同时躲开 35bp 的毒药和 8bp 的利润,而后者的样本量是前者的三倍。
这个结论是不是被我的参数设定钉死的?#
必须回答这个问题,否则前面所有数字都只是一次特定设定的读数。把无知情委托的强度从 0 扫到主导:

| 无知情委托占比 | 与知情相关 | 与总流量相关 | 前 10% 做市 P&L | 后 50% 做市 P&L |
|---|---|---|---|---|
| 0.0% | 0.998 | 0.998 | −37.41bp | −9.99bp |
| 5.0% | 0.709 | 0.997 | −32.17bp | −10.66bp |
| 10.4% | 0.304 | 0.998 | +3.73bp | −13.46bp |
| 12.7% | 0.332 | 0.996 | +8.65bp | −9.41bp |
| 13.3% | 0.379 | 0.996 | −4.06bp | −7.58bp |
| 22.1% | 0.196 | 0.996 | +26.40bp | −1.73bp |
这张表是全文最重要的证据。
在一个只有知情交易的世界里,VPIN 是个近乎完美的探测器(0.998),而且高 VPIN 时做市亏 37bp——教科书说的全对。 但只要掺进 5% 的无知情大额委托,相关性就掉到 0.709;到 10% 时掉到 0.304,同时做市 P&L 的符号翻转。
而与总不平衡流量的相关性在所有设定下都锁死在 0.996 以上。
所以 VPIN 不是一个坏指标,它是一个被误读的指标。 它稳定地测量它真正测量的东西(单边流量强度),只是这个东西和「知情概率」之间的映射,完全取决于你所在市场里那两类流量的构成比例——而这个比例恰恰是不可观测的。
对抗式检验:八项,含两个推翻常识的结果#
1. 纯噪声安慰剂。 无知情、无大额委托,VPIN 均值 0.024,标准差 0.0026。但注意:真实市场 100% 的桶都在安慰剂的 95 分位之上——绝对水平能区分「有没有结构」,只是区分不了「哪种结构」。
2. 零知情世界。 见上文,VPIN 保持真实市场的 99%。
3. 机械地板。 桶大小从 500 到 30000,零假设 VPIN 从 0.056 单调降到 0.008。
4. BVC 分类误差——反直觉结果。 真实场景拿不到方向标记,要用 BVC 从收益率推断。BVC 版 VPIN 与真实知情占比相关 0.354,而带完美方向标记的版本是 0.347——几乎没有损失,BVC 版甚至微幅更高。
这个结果一开始让我怀疑有 bug,查了三处:BVC 与带标记版本的相关只有 0.590(说明两者确实不同)、BVC 版均值 0.109 明显低于 0.153(说明分类确实在压缩失衡)、两者与总流量的相关都在 0.99 以上。结论是真的:瓶颈根本不在方向分类精度。 既然 VPIN 的上限由「区分不了两类单边流量」决定,那么改善方向分类精度就是在优化一个不是瓶颈的环节。文献里关于 Lee-Ready 对 BVC 的争论,在这个问题上意义有限。
5. 体积时钟 vs 钟表时间——第二个反直觉结果。 公平比较的前提是两者看到同样长度的历史:体积时钟窗口平均覆盖 1200.96 根 bar,我把钟表时间桶设为 24 根 bar × 50 = 1200 根,误差 0.08%。结果钟表时间版与知情占比相关 0.451,反而高于体积时钟的 0.347。
体积时钟的理论依据是「信息按成交量到达」,本文的模拟里这个假设成立(知情期成交量放大 2.2 倍)。即便如此,它也没有带来优势。 值得注意的是钟表时间版的知情事件基础发生率只有 0.38%(19 个事件),样本很小,所以这个方向性结论我只当作「体积时钟的优势没有被证实」,而不是「钟表时间更好」。
6. 打乱桶顺序。 保留全部桶的边际分布,只打乱顺序:标准差从 0.0548 降到 0.0266(降 51.4%),证明 VPIN 的波动一半来自事件的时间持续性,而非单桶的随机涨落。
7. 参数网格。 桶大小 {1000, 3000, 10000} × 窗口 {20, 50, 100}:VPIN 均值在 0.140~0.166 之间(摆动 18.0%),与知情占比的相关在 0.109~0.485 之间——相关性跨度 4.4 倍,这个指标对参数远比它的使用者以为的敏感。
8. 混合比例扫描。 见上节。
诚实边界#
第一,我的「知情」定义是一个模拟设定,不是市场事实。 我把知情定义为「带永久价格冲击的单边流量」。真实市场里永久/暂时的分解本身就是估计出来的(Hasbrouck、Glosten-Harris 等),有自己的误差。如果连真值都要估,那么本文这种「拿真值去评判指标」的做法在真实数据上无法直接复现。 这正是我用受控模拟的原因,也是这个结论无法用真实数据严格证伪的原因。
第二,10.39% 的无知情大额委托占比是我设的。 混合比例扫描已经说明结论完全取决于这个数字。真实市场的这个比例不可观测,且随品种和时段剧烈变化——大盘股指数调仓日和小盘股财报前夜,几乎是两个不同的世界。
第三,本文的做市 P&L 模型极度简化。 没有价差收入、没有库存管理、没有报价调整、没有手续费返还。真实做市商赚的是价差,逆向选择是成本项。说「高 VPIN 时做市反而赚钱」,严格的表述是「在这个只算价格漂移的口径下,高 VPIN 时段的漂移成本更低」——加上价差收入后结论可能不同。
第四,t 统计量假设桶之间独立,而它们高度重叠。 50 桶滚动窗口意味着相邻观测共享 49 个桶。文中的 t=4.14、t=−9.85 应视为方向性证据,真实自由度远低于名义值。
归宿#
三条可以直接用的结论:
VPIN 是流量结构指标,不是信息含量指标。 与总不平衡流量相关 0.996,与真实知情占比 0.347。把它当「知情交易概率」读,95 分位报警的假发现率是 85%,99 分位是 100%。
用它撤单之前,先想清楚你所在市场的流量构成。 只有知情交易的世界里它近乎完美;掺进 10% 的无知情大额委托,做市 P&L 的符号就翻转。同一条警报内部,知情主导的桶亏 35.4bp,大额委托主导的桶赚 7.96bp,而后者占 76%。
别把力气花在优化方向分类上。 BVC 与完美标记的结果几乎相同(0.354 对 0.347),公平匹配窗口后体积时钟也没有优势(0.347 对 0.451)。瓶颈不在工程细节,在这个统计量的定义本身就无法区分两类单边流量。要真正识别知情交易,必须引入价格的后续行为——永久冲击与暂时冲击的分解——而那已经不是 VPIN 能做的事了。
相关阅读:交叉冲击讨论了大额委托在多资产上的成本结构;Microprice 微观价格和限价单排队位置分别处理盘口定价与成交概率的另外两个侧面。