halo 的技术博客

返回

一、一条听起来无可辩驳的规则#

美国证券市场有一条几乎没人公开反对的规则:你不能以劣于全国最优报价的价格成交。

这就是 Reg NMS 的 Rule 611,通称穿价规则(trade-through rule)。逻辑非常直白:如果 A 交易所卖一挂 50.01,你却跑去 B 交易所以 50.02 成交,那么挂在 A 的那个投资者被无视了,而买方也多付了钱。规则要求你先去打 50.01。

这条规则保护的对象是显示报价(displayed quote):只要一个场所把价格挂出来、公开可见、可自动执行,它就进入全国最优买卖报价(NBBO),任何人都不得越过它成交。

问题在于,这条规则保护的是价格,而价格只是执行成本的一部分

一个只挂 100 股的小场所可以用一分钱的优势锁定 NBBO,逼着所有人先去打它。你打了,成交 100 股,然后剩下 4900 股的意图已经暴露在全市场的行情带上。等你回头去打真正有深度的场所时,价格已经不在那儿了。

这篇文章要量化的就是这个缺口:为了遵守一条保护价格的规则,你在别的地方付了多少钱。

我构造了一个 12 个场所的受控市场,每一笔成本的真实成因都由构造已知,然后对比四种路由政策。核心结论提前说:

规则的成本不主要来自「打了哪个价格」,而来自「必须一个一个打」。


二、模型:12 个场所,三个层级#

真实美国股市有 16 家注册交易所加几十个另类交易系统。我压缩成 12 个场所,分三层:

三层的关键差异在于报价激进度和深度的反向关系

# 报价偏离公允卖一的 tick 数分布:小场最常设定内盘价
DELTA_P  = {0: [.16,.30,.32,.22], 1: [.20,.34,.31,.15], 2: [.58,.28,.14,.00]}
# 显示量的对数正态中位数(股)
SIZE_MED = {0: 2600., 1: 700., 2: 150.}
SIZE_SIG = {0: 0.55,  1: 0.70, 2: 0.60}
python

小场所有 58% 的概率把报价挂在最激进的价位上,但中位显示量只有 150 股;主板报价保守得多,中位量却是 2600 股。这不是我强行设定的对立,而是经济上的必然:用 100 股锁定 NBBO 的成本极低,用 2600 股锁定的风险极高。

两个成本机制:

LAM_FLICK = 2.7e-4          # 每微秒的自然撤单强度(报价闪烁)
A_HOP     = 0.145           # 每次打印(tape event)的泄漏权重
B_VOL     = 0.85            # 累计成交量的泄漏权重
FADE_P    = 0.62            # 泄漏命中后单个场所退避的概率
DEEP_MIN  = 500             # 「小额报价」门槛(股)

def leak_hazard(hops, revealed, Q):
    """你已经打了几枪、成交了多少,决定了别人看见你的概率"""
    return 1.0 - np.exp(-(A_HOP * hops + B_VOL * revealed / max(Q, 1.0)))
python

第一个是闪烁:你的单子飞在路上时,报价可能已经撤了。第二个是足迹泄漏:每一次成交都会打印到行情带上,别人看见了就抬价撤量。后者是这篇文章的主角。


三、四种路由政策#

为了把「规则的成本」和「顺序执行的成本」分开,我需要四个而不是两个对照:

政策是否可穿价是否可并行含义
无约束前沿反事实理想:按净价挑,一次性并行发单
可穿价但顺序只解除排序约束,仍逐档打
R611 顺序合规现实中最常见的合规路由
ISO 扫单豁免用 ISO 标记一次性扫掉所有受保护报价

第三种是绝大多数券商的默认行为;第四种是规则自己开的后门——Intermarket Sweep Order 允许你同时向所有受保护报价发单,代价是你必须自己承担合规责任。

R611 的核心约束是必须按显示价排序,不能按净价:

while filled < Q:
    live = [k for k in range(K) if S[k] > 0]
    if not live: break
    k = min(live, key=lambda z: (A[z], LAT[z]))   # 只看显示价,不看费用
    take(k, Q - filled)
    propagate(k)                                  # 每打一档,泄漏一次
python

无约束前沿则是并行的,而且允许跳过净价没有优势的小额报价:

deepnet = min([A0[z] + FEE[z] for z in range(K) if S0[z] >= DEEP_MIN])
keep = [z for z in range(K)
        if S0[z] >= DEEP_MIN or (A0[z] + FEE[z]) < deepnet - 1e-12]
for k in sorted(keep, key=lambda z: (A0[z] + FEE[z], -S0[z])):
    take(k, Q - filled)      # 全部同时发出,飞行途中无人能退避
python

成本按三个桶分解,且必须满足恒等式 执行落差 = 显示价 + 退避 + 费用

AC0 分解恒等式最大残差 5.818e-13
plaintext

恒等式成立不代表桶的标签是对的——这一点后面用安慰剂来验。


四、基准结果:规则的税,1.207 个基点#

5000 股母单,4000 次重复:

成本分解

政策执行落差显示价退避费用平均跳数落空次数
无约束前沿4.121bp3.5560.0090.5565.230.42
可穿价但顺序5.079bp3.5610.9550.5637.730.60
R611 顺序合规5.328bp3.5331.2260.5698.280.66
ISO 扫单豁免3.976bp3.4090.0020.5646.310.55

合规成本 = R611 − 无约束前沿 = +1.207bp。

但这个数字必须拆开看,而拆开之后结论完全变了:

  • 被迫顺序执行的代价(可穿价但顺序 − 前沿):+0.958bp
  • 排序约束本身的额外代价(R611 − 可穿价但顺序):+0.250bp

79.4% 的合规成本来自「必须一个一个打」,只有 20.6% 来自「必须按显示价排序」。

这个拆分很重要,因为公共讨论几乎全部聚焦在后者——「凭什么强迫我去打那个 100 股的报价」。而数据说:真正贵的不是你打了哪个价,是你在打的过程中把自己暴露了 8.28 次。

看退避那一列就明白了:前沿是 0.009bp,R611 是 1.226bp,相差 136 倍。而显示价那一列,R611 反而是三者中最低的 3.533——规则确实让你拿到了更好的显示价,它没撒谎。它只是让你为此付了别的钱。

ISO 的读数更刺眼:−0.145bp。

也就是说,会用扫单豁免的券商,执行成本比无约束前沿还低。原因是 ISO 既拿到了规则强制的最优显示价,又通过并行发单规避了泄漏——两头的好处都占了。它比 R611 顺序路由省 1.395bp。

规则对所有人一视同仁,但豁免通道只对有能力用它的人开放。


五、三个安慰剂:成本到底从哪来#

这是全文最硬的部分。逐一把机制关掉,看成本去哪了。

安慰剂

场景无约束前沿R611R611 合规成本ISO 合规成本
基准4.1215.328+1.207bp−0.145bp
零泄漏(打印不被看见)4.1453.987−0.158bp−0.162bp
零延迟(报价不闪烁)3.9745.118+1.143bp−0.137bp
零优势(所有场所同价)2.5372.744+0.207bp+0.063bp

零泄漏安慰剂是决定性的。 把「别人能看见你的成交」这个机制彻底关掉,R611 的合规成本从 +1.207bp 塌到 −0.158bp——不仅归零,还略微转负(因为规则确实带来了更好的显示价,而此时没有任何代价抵消它)。

这意味着穿价规则的成本 100% 来自信息泄漏,0% 来自价格排序本身。 如果市场是完全不透明的,这条规则就是纯收益。

零延迟安慰剂排除了另一个嫌疑人。 把所有延迟设成 0、报价永不闪烁,合规成本只从 1.207 降到 1.143bp(降幅 5.3%)。「跑到了单子没了」不是主要成本来源——这一点反直觉,因为业界抱怨闪烁报价的声量远大于抱怨泄漏。

零优势安慰剂做的是压力测试。 让所有场所报同一个价,此时 NBBO 排序完全无意义,合规成本降到 +0.207bp。剩下这一点来自于:即使价格相同,R611 仍然强制你逐档遍历,而前沿可以跳过小额档直接打深度。

三条对照合起来锁死了因果链:规则 → 强制顺序遍历 → 打印次数增加 → 足迹泄漏 → 其他场所退避 → 你追高。

种子稳定性:12 个独立种子下 R611 合规成本均值 1.231bp、标准差 0.047、CV 0.038。


六、结构性错配:谁设定价格,谁提供深度#

谁设定 NBBO

  • 小场所设定了 71.2% 的 NBBO 卖一
  • 但只握有 20.7% 的显示深度(NBBO 档平均 2809 股,全场 13500 股左右)

这就是穿价规则的结构性问题:定价权和供给能力分离了。

用 150 股锁定 NBBO 的场所,获得了强制所有订单流先来敲门的法定权利。它提供的流动性不足以填满一笔中等规模的机构订单,但它有权让每一笔订单都先在它这里打一枪、留一个印子。

这不是钻空子,是规则的直接推论:Rule 611 保护的是受保护报价(protected quotation),门槛是「自动执行、公开显示」,没有最小数量要求


七、费后倒挂:25.7% 的受保护报价其实更贵#

穿价规则比较的是显示价,但你实际付的是显示价 + 交易所费用。美国交易所的 taker fee 上限是每股 0.0030,而反向定价场所(invertedvenue)反而给你返佣。最大费差0.0030,而反向定价场所(inverted venue)反而给你返佣。最大费差 0.0034,是 tick 的三分之一。

费后倒挂

在受保护的小额报价中,25.7% 费后反而比深度场所更贵

但这里有个必须说清楚的细节,否则这个数字会被误读:

其中显示价严格更优却净价更贵:0.0%
其中显示价打平但净价更贵:    25.7%
plaintext

没有一笔是「显示价明明更好、净价却更差」。 在 1 分钱的 tick 网格下,$0.0034 的费差根本无法跨越一个 tick——真正的价格倒挂在数学上不可能发生。25.7% 全部来自同价打平:多个场所显示同一个价格,规则对它们一视同仁,但净价差了 0.34 个 tick。

这个区分很重要,也解释了为什么 tick 尺寸是关键变量:

tick 与费后倒挂

tick费差/tickNBBO 多场打平率倒挂率其中严格倒挂
$0.05000.07100.0%49.7%0.00%
$0.02000.1775.1%23.7%0.00%
$0.01000.3467.9%21.3%0.00%
$0.00500.6848.1%10.3%0.00%
$0.00201.7023.8%4.3%0.53%
$0.00103.4012.3%2.6%0.73%
$0.00056.806.3%1.8%0.70%

tick 细于费差之后($0.0020 起),才第一次出现真正的严格倒挂。 在此之前,费用的影响全部被「同价」这个粗粒度掩盖了。

这给出一个不太直观的政策推论:缩小 tick 会同时减少总倒挂率(49.7%→1.8%)却引入严格倒挂(0%→0.7%)。前者是好事(费用不再被同价掩盖),后者是新问题(规则会真的强迫你去打净价更差的价格)。2024 年 SEC 通过的 tick 尺寸改革(部分股票降到 $0.005)正处在这条曲线的中段。


八、规模效应:小单免疫,大单挨打#

订单规模

母单规模无约束前沿R611R611 合规成本折合美元ISO 合规成本
100 股2.110bp2.583+0.473bp$0.02+0.462bp
500 股2.4982.761+0.263bp$0.66+0.172bp
2,000 股3.3273.775+0.448bp$4.5−0.086bp
5,000 股4.1075.378+1.271bp$32−0.141bp
10,000 股5.3457.141+1.796bp$90−0.188bp
20,000 股7.5809.571+1.991bp$199−0.138bp
50,000 股13.81215.843+2.031bp$508−0.142bp

两个读数:

规则的收益封顶,成本不封顶。 价格改善的上限就是一个 tick 乘以受保护报价的数量——那点量是固定的。而泄漏成本随着你需要遍历的档数增长。100 股时规则只花你 0.473bp(因为一枪就打完了,根本没有泄漏),5 万股时是 2.031bp。

ISO 的合规成本在 2000 股以上稳定在 −0.09 到 −0.19bp 之间。 也就是说,规模越大,会用 ISO 的人和不会用的人差距越大:5 万股时两者相差 2.17bp,折合 $543/笔。

这解释了一个现实现象:大型机构的执行成本优势,有相当一部分不来自更好的模型,而来自更完整的合规基础设施。


九、闪烁的影响:确实存在,但不是主角#

闪烁与延迟

平均往返延迟R611 执行落差落空次数总跳数
0μs5.198bp0.007.99
100μs5.302bp0.228.22
400μs5.277bp0.778.10
800μs5.649bp1.618.96
1600μs6.124bp3.2010.03

延迟从 0 到 1600μs(80 倍),执行落差只从 5.198 涨到 6.124bp(+17.8%)。而落空次数从 0 涨到 3.20 次——你扑空的次数增加了很多,但每次扑空的代价不大,因为扑空本身不产生打印,也就不产生泄漏。

这与上一篇讲延迟套利的文章形成有意思的对照:在主动扫单的场景里,延迟的边际价值远低于在被动做市场景里。 速度买的是「不被别人抢先」,而这里的成本来自「自己的动作被别人看见」——那是完全不同的两回事。


十、已知偏差#

1. 退避强度是校准的,不是实测的。 A_HOP=0.145B_VOL=0.85FADE_P=0.62 这三个参数直接决定了泄漏成本的量级,而它们在真实市场中根本不可直接观测——你看不到「如果我没打这一枪,那个报价会不会还在」。所有具体数字(1.207bp、0.958bp、136 倍)都依赖这套校准。不依赖校准的是三条结构性结论:零泄漏安慰剂的方向、顺序/排序的分解比例排序、规模效应的单调性。

2. 单资产、单时点、静态参与者。 我模拟的是一个价格 50 美元、价差 2 tick 的中等流动性股票在某一瞬间的快照。真实执行是跨时间的——算法会把母单切片、择时、在多个价格档位间等待。更重要的是,真实的对手方会适应:如果所有人都开始用 ISO,泄漏模式会重新均衡,我这套静态参数就不再适用。

3. 没有建模暗池和订单流内化。 现实中相当大比例的散户订单从不接触公开市场,而是被做市商内化执行。这些流量不受 Rule 611 约束(它们提供价格改善),但它们的存在改变了公开市场上剩余流量的构成。忽略这一块意味着我可能高估了公开市场的泄漏强度。

4. 「无约束前沿」是一个反事实,不是一个可选政策。 如果真的废除穿价规则,市场结构会重新均衡——小场所可能不再有动力挂内盘价,NBBO 的构成会完全改变。我测的是「在当前报价结构下,约束值多少钱」,不是「废除规则会怎样」。 这两个问题的答案可能差很远。

5. 费用结构简化。 真实的交易所费率有分层(按月成交量给不同档位)、有做市商专属折扣、有流动性提供返佣。我用了一组静态的 taker fee,且没有建模「同一家券商在不同场所有不同费率」这个非常真实的因素。


十一、结果解读#

最该被记住的是那个 79.4% / 20.6% 的分解。 关于穿价规则的公共辩论几乎全部围绕「凭什么强迫我打那个 100 股报价」,而模拟说这只占成本的五分之一。真正的税是顺序性——规则的合规方式要求你把一笔大单拆成 8.28 次公开打印,而每一次打印都在告诉市场「有人在买」。

这给出一个明确的政策方向:与其争论要不要废除穿价规则,不如让并行执行变得更容易。 ISO 已经是这个方向的机制,但它把合规责任转嫁给了券商——你必须自己证明你同时向所有受保护报价发了单。这道门槛把中小券商挡在外面,结果是一条旨在保护所有投资者的规则,实际效果是给有合规基础设施的机构发了一张 1.395bp 的优惠券

零泄漏安慰剂应该成为这类研究的标准动作。 把「信息可见性」关掉再跑一遍,如果你的成本估计归零,说明你测的是信息成本;如果不归零,说明还有别的机制在起作用。这个检验很便宜,但在市场微观结构的实证文献里极少看到——因为真实数据里你没法关掉可见性,只有在模拟里能做。

费后倒挂那 25.7% 需要被正确读解。 它不是「规则强迫你付更贵的价」,而是「规则在一个太粗的价格网格上做比较,看不见费用」。这个区分决定了应对方式:如果是前者,该改的是规则;如果是后者,该改的是 tick 尺寸或者费用透明度。数据支持后者——严格倒挂在 1 分钱 tick 下精确为 0

规模效应告诉你什么时候该在意这件事。 如果你的典型订单是 500 股,合规成本 0.263bp,折合 0.66,不值得为此做任何工程投入。如果是5万股,2.031bp折合0.66,不值得为此做任何工程投入。如果是 5 万股,2.031bp 折合 508,一年 1000 笔就是 50 万美元——那就值得认真评估 ISO 能力了。先算你自己的规模落在曲线的哪一段,再决定要不要花钱。

最后一条,也是最容易被忽略的:这条规则可能仍然是净收益的。 我全程测的是「合规相对于无约束的成本」,但无约束世界里 NBBO 的构成会完全不同,小场所也许根本不会挂内盘价,价差可能更宽。1.207bp 是约束的价格,不是废除的收益。 任何拿这个数字去论证「应该废除 Rule 611」的说法,都跳过了一整个均衡分析。

穿价规则与全国最优报价:订单路由的合规约束成本
https://blog.halo26812.eu.org/blog/trade-through-rule-nbbo
Author halo
Published at 2026年8月6日
版权声明 CC BY-NC-SA 4.0
Comment seems to stuck. Try to refresh?✨