第 21b 章 交易成本度量(下):计量估计、机会成本与成本预测
对应 Harris《Trading and Exchanges》第 21 章后半部分(21.5–21.11)。第 21a 章讲的是“指定一个基准价,然后比较”;本章讲三件事:没有报价数据时如何用统计方法估计成本(价格反转模型、Roll 估计量、Glosten–Harris 订单流回归);如何度量没成交的代价,以及它与交易成本之间的权衡(Plexus 成本冰山);如何预测未来交易成本。最后是作者关于策略师与交易员如何合作的结语。
学习目标
读完本章,你应当能够:
- 说明价格反转模型与订单流模型各自利用了什么信息、适用于什么场合。
- 解释平均绝对价格变化与 Roll 估计量为何会低估价差,并推导价差含逆向选择成分时 Roll 估计量的取值 \(S\sqrt{1-\alpha}\)。
- 写出 Glosten–Harris 模型 \(\Delta P_t=\lambda Q_t\text{Size}_t+a\Delta Q_t+b\Delta(Q_t\text{Size}_t)+\varepsilon_t\),并用回归分离永久冲击与暂时冲击。
- 计算错失交易机会成本,说明“何时度量”与“订单是否现实”两个难点,以及激进程度的边际条件。
- 把执行差额分解为经理择时、交易员择时、市场冲击、佣金、错失机会五项(Plexus 冰山)。
- 列出成本预测模型的三类解释变量,并用非线性回归拟合“成本随规模的幂律”模型。
读前导读
这一章在解决什么问题。 上一章的方法都要求你知道报价、知道决策时间。本章处理三个更难的情形。第一,手里只有成交价,没有报价(老数据、场内喊价的期货),怎么估计成本:靠价格反转(Roll)或把价格变化回归到订单流上(Glosten–Harris)。第二,订单没成交,损失怎么算:机会成本,以及它和交易成本此消彼长的关系。第三,还没交易,怎么预测成本:用历史订单拟合"成本随规模上升"的曲线。最后一段讲组合经理与交易员如何分工。
对 CFA 读者,这一章有两个熟悉的落点。一是 Plexus 冰山,它就是三级教材里执行差额分解(延迟成本、市场冲击、机会成本)的原型,你会看到这个分解为什么是一个"逐段相减再加总"的恒等式。二是 Glosten–Harris 回归,它在结构上和 CFA 二级的多元回归一样,只是你需要先把一个经济模型(价格 = 价值 + 暂时成分)变形成可以回归的形式。
需要先想起来的数学。
- 协方差展开。 与第 20 章相同:把两个相邻价格变化各写成若干项之和,两两配对,只有共同的随机项贡献协方差。见 第 00 册第 07 章 概率中的分析工具。
- 差分运算。 \(\Delta X_t=X_t-X_{t-1}\)。若 \(P_t=V_t+C_t\),则 \(\Delta P_t=\Delta V_t+\Delta C_t\);乘以常数的项差分后仍乘该常数,\(\Delta(aQ_t)=a\Delta Q_t\)。
- 一阶条件(边际相等)。 选择激进程度 \(k\) 使总成本 \(TC(k)+OC(k)\) 最小,对 \(k\) 求导令其为零:\(TC'(k)=-OC'(k)\),即"多激进一点多付的交易成本 = 因此少付的机会成本"。见 第 00 册第 02 章 导数与泰勒展开。
- 幂函数与弹性。 \(y=Yx^\delta\) 取对数得 \(\ln y=\ln Y+\delta\ln x\),\(\delta\) 是弹性:规模变为原来的 2 倍,单位成本变为 \(2^\delta\) 倍。\(\delta=0.5\) 时约 1.41 倍。这和你熟悉的价格需求弹性同义。见 第 00 册第 04 章 级数与收敛 的指数对数部分。
- OLS 一致性的条件。 只要误差项与解释变量不相关,样本越大,OLS 估计越接近真值。这是 CFA 二级回归假设里"外生性"的要求。
怎么读这一章。 21.5.1 中 Roll 估计量偏低的推导和 21.5.2 的 Glosten–Harris 模型是计量部分的核心,有逐笔数据需求的读者必读,其他读者可以只看结论:Roll 只看得见会回复的那部分价差。21.6 机会成本和 Plexus 冰山对所有读者都重要,必读。21.7 成本预测与量化补充里的平方根冲击律,是今天组合优化中成本项的来源,建议读懂。21.8 结语篇幅短,值得一读。
21.5 用计量方法度量隐性交易成本
计量模型用统计方法度量交易者对价格的冲击,一般考察两类信息:价格反转,或订单流与价格变化的关系。它们通常在没有报价或订单流数据时使用——例如公开喊价的期货市场很少记录场内喊出的买卖价,市场报告员主要记录成交价,衡量这些市场的成本只能用不依赖报价的方法。计量模型一般估计整个市场的平均成本;关心具体某一笔交易时,仍用第 21a 章的指定基准法。
21.5.1 价格反转模型
最常见的反转来自买卖反弹;未知情买卖方的失衡也会造成更长期的反转(价值交易者发现机会后价格回归),时间尺度从日内到数月。
平均绝对成交价格变化是非常简单的估计量。当买卖价不变、所有成交都在买价或卖价时,相邻成交要么价格不变(同方向),要么恰好跳一个价差(反方向),所以只看发生了变化的成交,平均绝对价格变化恰好等于价差(若把不变的成交也算进去,方向随机时平均值是半个价差)。但现实中买卖价会变,也不是所有成交都在报价上:报价变动幅度小于价差时它倾向低估价差,否则倾向高估。剔除很小和很大的价格变化可以改善估计。
白话解释:为什么"把不变的成交也算进去"时平均是半个价差?报价不动时,相邻两笔成交方向相同(概率 1/2)则价格不变,绝对变化为 0;方向相反(概率 1/2)则跳一个价差 \(S\)。平均绝对变化 \(=\tfrac12\times0+\tfrac12\times S=S/2\)。只看发生了变化的那一半,平均才是 \(S\)。代码里的 0.0240 接近 \(S/2=0.02\) 再加上新闻带来的少量变动,正是这个原因。
基于序列协方差的估计量更好。 有效市场假说意味着没有交易成本时价格变化没有序列相关,所以负的序列协方差指示交易成本。最著名的就是第 20 章推导过的 Roll 估计量:
Roll 估计量在以下条件下无偏:样本大;激进买卖方随机、等概率到达;有效买卖价的变化与到达的交易者序列不相关。违反这些假设通常导致低估价差。所以作者建议只在没有报价数据时才用 Roll 方法。
为什么违反第三个假设会低估?设价差中含逆向选择成分:每笔成交后,报价中点朝成交方向永久移动 \(\alpha S/2\)(\(0\le\alpha\le1\)),即 \(M_{t+1}=M_t+\alpha\tfrac S2Q_t+e_t\),成交价 \(P_t=M_t+\tfrac S2Q_t\)。则
两个相邻价格变化中只有 \(Q_{t-1}\) 是共同的,其系数分别为 \(\tfrac S2\) 与 \((\alpha-1)\tfrac S2\),所以
直觉:逆向选择那部分价格变化不回复,Roll 只“看得见”会回复的那部分价差,即第 20 章所说的暂时性成分。
推导拆解:把两个相邻价格变化完整写出来。 第一步,由 \(P_t=M_t+\tfrac S2Q_t\) 和 \(M_t-M_{t-1}=\alpha\tfrac S2Q_{t-1}+e_{t-1}\),得 \(\Delta P_t=\alpha\tfrac S2Q_{t-1}+e_{t-1}+\tfrac S2Q_t-\tfrac S2Q_{t-1}=\tfrac S2Q_t+(\alpha-1)\tfrac S2Q_{t-1}+e_{t-1}\)。 第二步,同理 \(\Delta P_{t-1}=\tfrac S2Q_{t-1}+(\alpha-1)\tfrac S2Q_{t-2}+e_{t-2}\)。 第三步,两式中唯一共同的随机变量是 \(Q_{t-1}\):在 \(\Delta P_t\) 里系数为 \((\alpha-1)\tfrac S2\),在 \(\Delta P_{t-1}\) 里系数为 \(\tfrac S2\)。其他项(\(Q_t\)、\(Q_{t-2}\)、\(e\))彼此独立,协方差为零。所以 \(\mathrm{Cov}=(\alpha-1)\tfrac S2\cdot\tfrac S2\cdot\mathrm{Var}(Q_{t-1})=-(1-\alpha)\tfrac{S^2}4\)。 第四步,代入 Roll 公式:\(2\sqrt{(1-\alpha)S^2/4}=S\sqrt{1-\alpha}\)。 检查两端:\(\alpha=0\) 时回到第 20 章的纯买卖反弹,估计为 \(S\);\(\alpha=1\) 时价格变化完全不回复,协方差为零,Roll 估计为 0,尽管交易者每笔仍付了半个价差。练习 2 就是把这个关系反过来用:真实价差 \(=\) Roll 估计 \(/\sqrt{1-\alpha}\)。
21.5.2 订单流模型
更复杂的模型直接估计激进交易者造成的价格效应,通常用回归刻画价格如何响应订单流,原理是“激进买方推高、激进卖方压低价格”。一般先用 Lee–Ready 规则(第 21a 章)识别每笔成交的主动方,再用带符号的交易解释价格变化。
Glosten–Harris 模型(原书专栏“Glosten–Harris 遇见 Glosten–Milgrom”)是最简单的例子,基于第 14 章的 Glosten–Milgrom 价差成分模型。激进交易者对价格有两种效应:
- 永久效应(permanent effect):流动性提供者从订单流中推断出知情交易,对应第 13 章的逆向选择价差成分;信息论的考虑表明它应与交易规模成正比(见第 12、14 章)。
- 暂时效应(transitory effect):向急躁交易者提供流动性的成本,对应交易成本价差成分;可以有固定部分和与规模成比例的部分。
模型写成两条方程。观测价格 = 基本面价值 + 暂时成分:
基本面价值的变化来自从订单流推断的信息和其他信息 \(\varepsilon_t\):
合并得到可估计的回归方程:
被解释变量是成交价变化,三个回归元是带符号规模、交易符号的变化、带符号规模的变化。误差项 \(\varepsilon_t\) 是与订单流无关的价值变化,与回归元不相关,所以 OLS 一致。估计出 \(\lambda,a,b\) 后,对任意规模 \(x\) 的交易,永久冲击为 \(\lambda x\),暂时成本为 \(a+bx\)。
推导拆解:从两条方程到回归式只用了"差分"。 第一步,\(P_t=V_t+C_t\) 两边对 \(t\) 差分:\(\Delta P_t=\Delta V_t+\Delta C_t\)。 第二步,\(\Delta V_t\) 直接代入第二条方程:\(\lambda Q_t\text{Size}_t+\varepsilon_t\)。注意价值方程本身就是变化量,所以这一项不再差分。 第三步,\(\Delta C_t=(aQ_t+bQ_t\text{Size}_t)-(aQ_{t-1}+bQ_{t-1}\text{Size}_{t-1})=a\Delta Q_t+b\Delta(Q_t\text{Size}_t)\)。 合起来就是框中式子。为什么能把三种效应分开?因为它们在数据中的"形状"不同:永久效应只依赖本笔的带符号规模,不会反转;暂时效应依赖本笔与上一笔之差,下一笔就反向抵消。回归正是利用这种不同的时间形状来区分它们。 练习 3 的数字:2,000 股即 Size \(=20\),永久冲击 \(0.0004\times20=0.008\) 元,暂时成本 \(0.01+0.001\times20=0.03\) 元,合计 0.038 元/股。
Glosten–Harris 模型也可以理解为一种基准价模型,基准是不可观测的基本面价值 \(V\);它不需要估计基准就能给出成本估计,但需要时也容易把 \(V_t=P_t-C_t\) 算出来。
21.6 错失交易机会成本
不交易往往比交易更贵。 知情者订单没成交就失去了利润;未知情者没成交也可能受伤,尤其是在对冲时。所以必须同时关注机会成本与交易成本。一般度量为:
例(原书 DINE 例)。 交易者决定卖出 10 万股 DINE(Advantica Restaurant Group,Denny's 的所有者),当时中点 1.00 美元。他挂限价卖单,成交 3 万股,其余 7 万股始终没成交。现在价格 82 美分。以决策时中点为基准,执行差额口径的机会成本为 \(70{,}000\times0.18=\) 12,600 美元。
度量机会成本有两个度量交易成本时没有的难题:
- 何时度量? 若一周后 DINE 又回到 1.00 美元,估计的机会成本为零。甚至这也不一定对——如果当初以 1.00 卖出全部 10 万股,他可能在 82 美分时买回来,涨回 1.00 时就又错过了 18,000 美元。实务中在首次决定交易或最终放弃订单后的某个固定区间(一天、一周、一个月)度量。
- 订单是真实的,还是一厢情愿的(wishful)? 如果他想卖的不是 10 万股而是 400 万股——占总股本 10%、是日均成交量 8 万股的 50 倍——则未成交 3,970,000 股的机会成本为 714,600 美元。这严重高估了真实的机会成本:他无论如何不可能在不把价格压到 82 美分以下的情况下卖出这么多,从来就没有赚 714,600 美元的机会。机会成本必须以订单规模合理为前提。
理论上正确的做法是用“在最有利条件下完成交易的平均价格”作基准,但这很难估计;实务中交易者只是监控订单,确保规模合理。机会成本可相对任何基准度量,最合理的是用与交易成本相同的基准,使两者可比、可以相加。
激进程度的边际条件。 如果更激进交易多付的交易成本,少于因此节省的机会成本,就应更激进;如果更不激进能省下的交易成本,多于因此多出的机会成本,就应更不激进。最优时两者在边际上相等(原书思考题 3)。实务中多数交易者不估计边际成本,而假设边际成本等于平均成本:单位机会成本大于单位交易成本就更激进,反之更不激进。关注此问题的交易者应该用填满订单的最后几笔成交的成本来估计边际交易成本——拆单时最后几笔最贵(第 21a 章)。
推导拆解:用一个变量 \(k\) 表示激进程度(例如限价离对手价的距离取负)。交易成本 \(TC(k)\) 随 \(k\) 上升,机会成本 \(OC(k)\) 随 \(k\) 下降(越激进越容易成交)。总成本 \(TC(k)+OC(k)\) 对 \(k\) 求导令其为零:\(TC'(k^*)+OC'(k^*)=0\),即 \(TC'(k^*)=-OC'(k^*)\)。左边是"再激进一点多付的交易成本",右边是"因此省下的机会成本",这就是原文的边际条件。 为什么不能用平均成本代替边际成本?拆单时成本逐笔上升,平均值低于最后一笔的成本。用平均值比较,会让人以为"再多做一点也很便宜",导致过度激进。这和企业定价里"边际成本高于平均成本时,按平均成本决策会过度扩产"是同一个错误。
Plexus 交易成本冰山
Plexus Group 把执行差额详细分解为四类(原书专栏 “The Plexus Iceberg of Transaction Costs”),以一张买单为例,各项都是“带符号的价格差 × 股数”:
| 成分 | 定义 | 衡量谁的责任期 |
|---|---|---|
| 经理择时(manager timing,又称系统/模型择时) | 决策价 → 订单交给买方交易台时的价格 | 组合经理。多数经理以前一日收盘为决策价;该项高的应更快把订单交给交易台 |
| 交易员择时(trader timing) | 交到交易台时的价格 → 交易台下给经纪商时的价格(拆单时逐块计算) | 买方交易台。交易台“兜售大宗”(shop a block,第 15 章)走漏风声、或拆单分时下单时,前面部分的冲击会造成后面部分的择时成本 |
| 市场冲击(market impact) | 下给经纪商时的价格 → 成交价(多笔分别计算) | 经纪商。多数交易者不让经纪商隔夜持有订单,所以这是日内效应;跨日部分计入交易员择时 |
| 错失机会(missed opportunity) | 未完成部分:决策价 → 决策后 30 个交易日的价格 | 整个链条 |
再加上佣金,各项之和等于总执行差额。
推导拆解:为什么各段相加恰好等于执行差额?对已成交部分,四个价格依次是决策价 \(p_{\text{dec}}\)、交台价 \(p_{\text{desk}}\)、下单价 \(p_{\text{broker}}\)、成交价 \(p\)。 \((p_{\text{desk}}-p_{\text{dec}})+(p_{\text{broker}}-p_{\text{desk}})+(p-p_{\text{broker}})=p-p_{\text{dec}}\), 中间的价格一正一负两两抵消,只剩首尾,这叫"裂项相消"(telescoping)。所以经理择时 + 交易员择时 + 市场冲击 = 已成交部分的执行差额,再加佣金和未成交部分的错失机会,就是第 21a 章的总执行差额。 这和 Brinson 归因的思路相通:都是把一个总差额沿一条链拆成若干段,每段对应一个责任人。区别在于 Brinson 按资产配置和证券选择横向拆,冰山按时间顺序纵向拆。量化实战二的代码最后一行"直接按定义计算 84,100"就是在验证这个恒等式。
冰山比喻:可见成本(佣金和市场冲击)是水面上的部分,不可见成本(择时和错失交易)是水下的大部分。Plexus 估计其客户平均支付佣金 12 个基点、市场冲击 20 个基点,因价格背离损失的择时成本 53 个基点,因订单未成交再损失 16 个基点。隐性的实施成本远大于可见成本。
Plexus 认为四项必须全部度量,因为成本很容易在类别之间转移。交易者要避开一个思维陷阱:可见成本看起来降低了,其实只是挪到了更隐蔽的择时类别——例如让经纪商极其被动地交易,冲击变小了,但价格在等待中跑掉了。
现状补充:Plexus Group 后来被 ITG 收购,ITG 又在 2019 年被 Virtu 收购;冰山式的分解至今仍是机构 TCA 报告的标准结构,只是今天的叫法多为“延迟成本(delay cost)”“执行成本”“机会成本”等。
21.7 交易成本预测
评估一个主动策略,必须先预测实施它的成本。预测用到两类信息。
21.7.1 显性信息
合同约定的佣金和费用;当前报价和公开限价簿揭示的流动性。交易规模小于盘口展示量时,可以有把握地得到冲击的上界(前提是能先于他人拿到这些流动性)。
但报价和限价簿很少揭示全部流动性。交易者常不展示全部意愿:怕被抢跑、不想送出期权价值、不想泄露价值或头寸信息、想避免向价格歧视者或知情者提供流动性(第 18 章)。所以常常能以比展示信息更好的价格或更大规模成交;要准确估计成本,必须估计展示流动性背后还可能藏着多少(回忆第 19 章表 19-1)。
21.7.2 隐性信息:用历史成本建模
即假设可以用过去订单的冲击预测未来订单的冲击。流动性条件不变时这成立,但大量证据表明流动性随时间变化,一些交易者尽量对这种变化建模。主要方法是计量回归模型,用可观测变量解释过去的交易成本,变量分三类:
| 类别 | 最重要的变量 | 其他变量 |
|---|---|---|
| 订单特征 | 订单规模、价格放置(激进程度) | — |
| 同期市场状况 | 买卖价差(宽度)、当前展示数量(深度) | 近期成交量、近期价格变化(动量)、资金流 |
| 一般市场状况 | 平均成交量、波动率 | 市值(大公司股票更流动) |
规律是:大单比小单贵;激进定价的订单通常更贵;活跃交易、价格稳定的市场成本低。
量化补充:业界常用的冲击模型把这三类变量组合成一个简洁的函数形式,例如
\[\text{成本(bp)}\approx c\cdot\text{价差(bp)}+Y\cdot\sigma_{\text{日}}\cdot\Big(\frac{\text{订单规模}}{\text{ADV}}\Big)^{\delta},\]其中 \(\delta\) 的经验估计多在 0.5 附近(即常说的“平方根冲击律”),\(Y\) 为量级在 1 附近的常数。它与原书的回归思路一致:规模用相对日均成交量(ADV)的比例刻画,波动率与价差作为市况变量。下面的代码演示如何从历史母单中拟合这种模型。
白话解释:这个式子有三个要点。其一,冲击项正比于日波动率 \(\sigma\):波动大的股票,同样的订单把价格推得更远,这和"高波动股票做市商要价更高"一致。其二,规模用"占日均成交量的比例"而不是股数衡量,这样不同股票可比:买 10 万股茅台和买 10 万股某小盘股完全不是一回事。其三,指数 \(\delta\approx0.5\) 意味着单位成本随规模以平方根增长:规模从 ADV 的 1% 到 4%,冲击项的单位成本翻倍而不是翻四倍;但总冲击成本(单位成本 × 规模)增长 8 倍,即与规模的 1.5 次方成正比。这就是代码解读里"规模放大 20 倍、总成本放大 88 倍"的原因(那里 \(\delta=0.6\),纯冲击项会放大 \(20^{1.6}\approx120\) 倍,价差项不随规模变化,把倍数稀释到约 88 倍)。
21.8 结语:策略师与交易员要合作
机构通常把交易实施与组合选择分开评估,但两者并非二分——策略制定者与执行交易员经常互动时,总体绩效往往更好:
- 策略师在采用策略前要知道交易成本,交易员要告诉他可行性:能交易多少、成本多少,才能形成使组合价值最优的订单。
- 策略师也要告诉交易员为何交易,以便交易员决定激进程度。基于短期信息时,必须让交易员激进交易,并给出反映信息价值的价格限制。知情者应愿意承担可观的交易成本,尤其是交易很短期的信息时,否则可能没成交而失去大笔利润。
- 评估方案不应使双方成为对手:策略师不应因“策略不能盈利是交易员的错”而受奖励,交易员也不应因“填不满不现实的大单是策略师的错”而受奖励。奖励总体绩效的联合激励合同为合作提供强激励;在无法区分各自贡献时,试图分别识别和奖励各自贡献的合同适得其反。
在量化机构中,这对应 alpha 研究与执行团队之间的接口:研究端要告诉执行端信号的衰减速度(决定执行紧迫度,urgency),执行端要把真实成本反馈给研究端(校准回测成本模型和组合优化中的成本惩罚项)。
21.9 小结
估计交易成本是为了更好地管理交易:判断佣金是否物有所值;在交易成本与错失机会成本之间平衡,优化下单策略;确保策略在实施时有利可图。成本度量有噪声,但能产生有价值的信息。作者的最后一个判断值得每个量化交易者记住:对许多投资经理而言,通过更有效的执行管理降低交易成本,比把同样资源投入改进组合选择更能提高绩效——降低成本往往比改进选股更容易、更可靠。
量化实战一:Glosten–Harris 回归与无报价的价差估计
第一段代码模拟 10 万笔成交,按 Glosten–Harris 模型生成价格,再用 OLS 回归恢复 \(\lambda,a,b\),并计算不同规模交易的永久/暂时成本;第二部分比较平均绝对价格变化和 Roll 估计量,并验证含逆向选择成分时 Roll 估计等于 \(S\sqrt{1-\alpha}\)。
import numpy as np, pandas as pd
import statsmodels.api as sm
rng = np.random.default_rng(211)
n = 100_000
# ---------- Glosten-Harris 模型 ----------
lam, a, b = 0.0004, 0.010, 0.0010 # 永久: λ·Q·Size;暂时: a·Q + b·Q·Size(Size 以百股计)
Q = rng.choice([-1, 1], n)
Size = rng.lognormal(mean=1.0, sigma=0.8, size=n).round(1) + 0.1 # 百股
eps = rng.normal(0, 0.01, n)
V = 30 + np.cumsum(lam * Q * Size + eps)
C = a * Q + b * Q * Size
P = V + C
dP = np.diff(P)
X = pd.DataFrame({"QSize": (Q * Size)[1:],
"dQ": np.diff(Q),
"dQSize": np.diff(Q * Size)})
fit = sm.OLS(dP, X).fit()
print("== Glosten-Harris 回归 ==")
print(pd.DataFrame({"真实值": [lam, a, b], "估计值": fit.params.values, "标准误": fit.bse.values},
index=["lambda(永久)", "a(暂时固定)", "b(暂时比例)"]).round(5).to_string())
for s in [1, 10, 50]:
perm, trans = fit.params["QSize"] * s, fit.params["dQ"] + fit.params["dQSize"] * s
print(f"规模 {s:>2} 百股的买单:永久冲击 {perm*100:.2f} 分,暂时成本 {trans*100:.2f} 分,"
f"半个有效价差约 {(perm + trans)*100:.2f} 分/股")
# ---------- 不用报价的价差估计:平均绝对价格变化 vs Roll ----------
S, sig = 0.04, 0.01
V2 = 30 + np.cumsum(rng.normal(0, sig, n))
Q2 = rng.choice([-1, 1], n)
P2 = V2 + 0.5 * S * Q2
d = np.diff(P2)
roll = 2 * np.sqrt(-np.cov(d[1:], d[:-1])[0, 1])
print(f"\n== 无报价时估计价差(真实 S={S})==")
print(f"平均绝对价格变化 {np.mean(np.abs(d)):.4f};剔除绝对值小于 1 分的变化后 {np.mean(np.abs(d[np.abs(d) >= 0.01])):.4f};Roll 估计 {roll:.4f}")
# 价差中含逆向选择成分:每笔成交后中点朝成交方向移动 alpha*S/2(不回复),违反 Roll 假设
alpha = 0.5
M = 30 + np.concatenate([[0.0], np.cumsum(alpha * S / 2 * Q2 + rng.normal(0, sig, n))[:-1]]) # 成交前中点
P3 = M + 0.5 * S * Q2
d3 = np.diff(P3)
c3 = np.cov(d3[1:], d3[:-1])[0, 1]
print(f"含逆向选择成分(alpha={alpha})时:Roll 估计 {2*np.sqrt(-c3):.4f},理论 S*sqrt(1-alpha) = {S*np.sqrt(1-alpha):.4f},"
f"而真实有效价差为 {np.mean(2*Q2*(P3-M)):.4f}")
输出:
== Glosten-Harris 回归 ==
真实值 估计值 标准误
lambda(永久) 0.0004 0.00040 0.00001
a(暂时固定) 0.0100 0.01001 0.00003
b(暂时比例) 0.0010 0.00099 0.00001
规模 1 百股的买单:永久冲击 0.04 分,暂时成本 1.10 分,半个有效价差约 1.14 分/股
规模 10 百股的买单:永久冲击 0.40 分,暂时成本 1.99 分,半个有效价差约 2.39 分/股
规模 50 百股的买单:永久冲击 2.00 分,暂时成本 5.96 分,半个有效价差约 7.96 分/股
== 无报价时估计价差(真实 S=0.04)==
平均绝对价格变化 0.0240;剔除绝对值小于 1 分的变化后 0.0341;Roll 估计 0.0400
含逆向选择成分(alpha=0.5)时:Roll 估计 0.0283,理论 S*sqrt(1-alpha) = 0.0283,而真实有效价差为 0.0400
要点:
- Glosten–Harris 回归把三类成本分得很干净,前提是交易方向分类正确、模型设定正确。实际数据中通常要加入更多滞后项、对 Size 取对数或分段、按日内时段分组;方向误分类会使 \(\lambda\) 和 \(b\) 向零偏。
- 成本随规模变化的结构:小单的成本几乎全是固定的暂时成本 \(a\);大单的永久冲击和比例成本迅速上升。这正是“冲击成本随规模非线性上升”的微观来源。
- 平均绝对价格变化在本例中只有 0.024,远低于价差 0.04——相邻同方向成交时价格只随新闻小幅变动,把平均值拉低了;剔除很小的变化后改善到 0.034(原书的建议),剩下的偏差来自报价本身的变动。
- Roll 估计量在纯买卖反弹模型下精确(0.0400),但价差中一半是逆向选择成分时只有 0.0283,与理论值 \(S\sqrt{1-\alpha}\) 一致,而真实有效价差仍是 0.04。所以 Roll 估计的是价差中的暂时性部分,用它作为回测成本会低估真实成本。
量化实战二:执行差额分解与冲击模型拟合
第二段代码:(1) 对一张买入母单做 Plexus 式分解(数字为示意);(2) 复算 DINE 例的两个机会成本;(3) 模拟 5,000 张历史母单的实现成本,用非线性最小二乘拟合“价差 + 幂律冲击”模型,再用它预测新订单的成本。
import numpy as np, pandas as pd
from scipy.optimize import curve_fit
# ---------- 1) Plexus 式执行差额分解(一张买入母单,数字为示意) ----------
X = 100_000 # 计划买入股数
p_dec = 50.00 # 决策价:经理决定交易时(常用前一日收盘)
p_desk = 50.20 # 订单交到买方交易台时的价格
p_broker = 50.35 # 交易台把订单下给经纪商时的价格
fills = [(30_000, 50.40), (30_000, 50.55), (20_000, 50.70)] # 经纪商的成交
comm_per_share = 0.02
p_later = 52.00 # 决策后 30 个交易日的价格(用于未成交部分)
Xf = sum(q for q, _ in fills); Xu = X - Xf
avg = sum(q * p for q, p in fills) / Xf
parts = {
"经理择时": Xf * (p_desk - p_dec),
"交易员择时": Xf * (p_broker - p_desk),
"市场冲击": sum(q * (p - p_broker) for q, p in fills),
"佣金": Xf * comm_per_share,
"错失机会": Xu * (p_later - p_dec),
}
paper_value = X * p_dec
total = sum(parts.values())
check = Xf * (avg - p_dec) + Xf * comm_per_share + Xu * (p_later - p_dec)
for k, v in parts.items():
print(f"{k:6s}: {v:>10,.0f} 美元 {v / paper_value * 1e4:6.1f} bp")
print(f"合计 : {total:>10,.0f} 美元 {total / paper_value * 1e4:6.1f} bp(直接按定义计算 {check:,.0f})")
# ---------- 2) 原书 DINE 例:机会成本与“一厢情愿”的订单 ----------
for want in [100_000, 4_000_000]:
unfilled = want - 30_000
print(f"想卖 {want:>9,} 股,未成交 {unfilled:>9,} 股,机会成本 = {unfilled * (1.00 - 0.82):>10,.0f} 美元")
# ---------- 3) 交易成本预测:用历史母单拟合冲击模型 ----------
rng = np.random.default_rng(213)
n = 5000
part = np.exp(rng.uniform(np.log(0.001), np.log(0.3), n)) # 订单规模 / 日均成交量
vol = rng.uniform(100, 400, n) # 日波动率(bp)
spread = rng.uniform(2, 30, n) # 报价价差(bp)
true = 0.5 * spread + 0.8 * vol * part ** 0.6
cost = true + rng.normal(0, 1, n) * vol * np.sqrt(part) * 0.5 + rng.normal(0, 5, n) # 实现成本噪声很大
def model(Xm, c, Y, delta):
s, v, x = Xm
return c * s + Y * v * x ** delta
(c, Y, delta), cov = curve_fit(model, (spread, vol, part), cost, p0=[0.5, 1.0, 0.5])
se = np.sqrt(np.diag(cov))
print(f"\n拟合:成本(bp) = {c:.2f}×价差 + {Y:.2f}×波动率×(规模/ADV)^{delta:.2f}"
f" [标准误 {se[0]:.2f}, {se[1]:.2f}, {se[2]:.2f}];真实为 0.5, 0.8, 0.6")
for x in [0.01, 0.05, 0.2]:
print(f" 预测:价差 10bp、波动率 200bp、规模占 ADV {x:>4.0%} -> {model((10, 200, x), c, Y, delta):6.1f} bp")
print(f"单笔实现成本与模型值的相关系数仅 {np.corrcoef(cost, true)[0,1]:.2f}——逐笔噪声很大,必须靠大量订单估计")
输出:
经理择时 : 16,000 美元 32.0 bp
交易员择时 : 12,000 美元 24.0 bp
市场冲击 : 14,500 美元 29.0 bp
佣金 : 1,600 美元 3.2 bp
错失机会 : 40,000 美元 80.0 bp
合计 : 84,100 美元 168.2 bp(直接按定义计算 84,100)
想卖 100,000 股,未成交 70,000 股,机会成本 = 12,600 美元
想卖 4,000,000 股,未成交 3,970,000 股,机会成本 = 714,600 美元
拟合:成本(bp) = 0.48×价差 + 0.80×波动率×(规模/ADV)^0.60 [标准误 0.04, 0.03, 0.02];真实为 0.5, 0.8, 0.6
预测:价差 10bp、波动率 200bp、规模占 ADV 1% -> 15.0 bp
预测:价差 10bp、波动率 200bp、规模占 ADV 5% -> 31.6 bp
预测:价差 10bp、波动率 200bp、规模占 ADV 20% -> 66.1 bp
单笔实现成本与模型值的相关系数仅 0.68——逐笔噪声很大,必须靠大量订单估计
解读:
- 冰山的形状:这张示意订单的“可见成本”(佣金 3.2bp + 市场冲击 29bp)只占总执行差额 168bp 的五分之一;经理和交易员两段择时合计 56bp,错失机会 80bp。如果只考核经纪商的市场冲击,就看不到大部分成本。分解的意义在于把责任落到链条上的每一环:经理择时高,说明决策到下单之间延误太久;交易员择时高,说明交易台在走漏消息或分批太慢;错失机会高,说明执行太被动。
- DINE 例说明机会成本对订单规模是否现实极其敏感:同样的价格路径,“想卖 400 万股”的机会成本是 714,600 美元,而这个数字毫无意义。量化系统中,目标仓位应受容量约束(例如单日不超过 ADV 的某个比例),否则机会成本统计会被不现实的目标污染。
- 冲击模型拟合:只要样本足够大,非线性最小二乘能较准确地恢复价差系数、冲击系数和幂指数。模型预测“规模占 ADV 从 1% 到 20%,成本从 15bp 升到 66bp”——规模放大 20 倍,成本只放大约 4.4 倍,但总成本(成本率 × 规模)放大了 88 倍。这就是策略容量问题的根源。
- 单笔成本噪声极大:实现成本中包含大量与执行无关的价格变动,单笔的模型拟合度有限。这与第 21a 章“对单笔交易所有估计都有噪声,要靠大量交易平均”的结论一致;在实际 TCA 中,常用数千到数万张母单才能稳定估计冲击参数。
本章小结
没有报价数据时,可用计量方法估计市场平均的交易成本:价格反转模型(平均绝对价格变化、Roll 估计量)只利用价格,会低估价差,Roll 估计的实际上是暂时性成分;订单流模型(Glosten–Harris)把价格变化回归到带符号的交易上,分离出与规模成正比的永久冲击和固定加比例的暂时成本。机会成本 = 未成交量 × 方向 × (后续价格 − 基准),要定好度量时点、排除不现实订单,并与交易成本用同一基准;最优的激进程度使边际交易成本等于边际机会成本。Plexus 冰山显示隐性成本(择时和错失机会)远大于可见成本。成本预测用订单特征、同期市况、一般市况三类变量建模。策略师与交易员应在联合激励下合作。
| 概念/公式 | 要点 |
|---|---|
| 计量法适用场合 | 无报价/订单流数据;估计市场平均成本 |
| 平均绝对价格变化 | 简单;报价变动小于价差时低估、大于时高估;剔除极端值可改善 |
| Roll 估计量 | \(2\sqrt{-\text{SCov}}\);含逆向选择成分时为 \(S\sqrt{1-\alpha}\),偏低 |
| Glosten–Harris | \(\Delta P_t=\lambda Q_t\text{Size}_t+a\Delta Q_t+b\Delta(Q_t\text{Size}_t)+\varepsilon_t\) |
| 永久 / 暂时冲击 | \(\lambda x\)(逆向选择)/ \(a+bx\)(流动性提供成本) |
| 机会成本 | 未成交量 × \(Q\) ×(后续价格 − 基准);DINE:12,600 美元 vs 不现实订单 714,600 美元 |
| 激进程度 | 边际交易成本 = 边际机会成本;用最后几笔成交估计边际成本 |
| Plexus 冰山 | 佣金 12bp、冲击 20bp、择时 53bp、未成交 16bp |
| 成本预测变量 | 订单规模与激进程度;价差与深度;成交量、波动率、市值 |
| 冲击模型 | 成本 ≈ \(c\cdot\)价差 \(+Y\sigma(x/\text{ADV})^{\delta}\),\(\delta\) 常在 0.5 附近 |
练习
基础
- 为什么计量方法更适合估计整个市场的平均成本,而不适合评估某一笔交易?
- 某期货合约只有成交价数据,相邻成交价变化的样本自协方差为 −0.0009(点²)。用 Roll 方法估计价差;如果你知道价差中约一半是逆向选择成分,真实价差大约是多少? 答案:Roll 估计 \(2\sqrt{0.0009}=0.06\) 点;若 \(\alpha=0.5\),真实价差约 \(0.06/\sqrt{0.5}\approx0.085\) 点。
- 用 Glosten–Harris 的估计 \(\lambda=0.0004\)、\(a=0.01\)、\(b=0.001\)(Size 以百股计):一笔 2,000 股的买单,永久冲击、暂时成本各是多少? 答案:Size=20;永久 \(0.008\) 元;暂时 \(0.01+0.02=0.03\) 元;合计 0.038 元/股。
- 列出 Plexus 冰山的四个成分,并说明每一项主要由谁负责。
- 交易者想买 5 万股,决策时中点 20.00,成交 4 万股均价 20.06,其余未成交,一周后价格 20.50。计算执行差额(不计佣金)及其两部分。 答案:已成交 \(40{,}000\times0.06=2{,}400\);机会成本 \(10{,}000\times0.50=5{,}000\);合计 7,400 美元。
进阶
- 原书思考题 3:交易者优化交易时,错失机会成本与交易成本之间是什么关系?用一个限价单距离的例子(参考第 18 章的模拟)说明。 答案要点:最优点处两者边际相等;限价每向市场靠近一档,成交部分多付的成本应恰好等于因成交概率提高而减少的机会成本。
- 原书思考题 4:哪些类型的逐利交易者测得的交易成本应较高?哪些较低? 提示:需求流动性者(急躁的知情者、动量交易者)高;提供流动性者(做市商、价值交易者)低甚至为负;知情者用事后基准测得偏低。
- 在本章 Glosten–Harris 代码中,随机把 10% 的交易方向 \(Q\) 翻转(模拟 Lee–Ready 误分类)后再回归,观察 \(\lambda,a,b\) 的估计偏差。
- 修改冲击模型代码,把样本量从 5,000 降到 200,重复多次,观察幂指数 \(\delta\) 估计的分布。你的结论对“用自己的少量历史订单校准成本模型”意味着什么?
- 原书思考题 1:除了低交易成本,经纪商还应提供哪些服务? 提示:研究、搜寻对手(尤其大宗)、保密、资本承诺、清算结算、择时判断等。
原书推荐习题:思考题 3(机会成本与交易成本的边际关系,联系最优执行);思考题 4;思考题 1。另建议用逐笔数据估计 Glosten–Harris 的 \(\lambda,a,b\),并与第 21a 章的有效价差、已实现价差比较。
原书对照
- 原书第 21 章后半部分,PDF 第 445–454 页(原书页码约为 PDF 页码减 13,即第 432–441 页):
- 21.5 计量方法(价格反转模型、订单流模型,专栏 “Glosten–Harris Meets Glosten–Milgrom”):PDF p.445–448;
- 21.6 错失交易机会成本(DINE 例、专栏 “The Plexus Iceberg of Transaction Costs”):p.447–451;
- 21.7 交易成本预测:p.451–452;
- 21.8 关于明智的交易成本管理的结语:p.452–453;
- 21.9 总结、21.10 要点回顾:p.453–454;21.11 思考题:p.454。
- 前半部分(21.1–21.4)见第 21a 章。