VWAP 和 TWAP 执行算法:它们怎么工作,什么时候失效
VWAP 和 TWAP 是行业里用得最多的两个执行算法,也是被误解最多的。这篇从基准定义讲到成交量预测,再把四种失败方式一个个拆开:羊群、错预测、被检测、丢 alpha。
如果你在机构交易 desk 周围待过,你会听到 VWAP 和 TWAP 被念叨得跟魔法咒语一样。它们不是魔法,是把父单切成子单、摊到时间上去成交的简单算法。但这里藏着一个值得琢磨的问题:这两个算法的目标不过是”成交在平均价附近”——听起来谦虚得不能再谦虚——为什么还是有那么多种方式把它搞砸?这篇文章就沿着这个问题走:先讲清两个基准是什么,再讲算法怎么追它们,最后把四种失败方式一个个拆开。
Harris 在第 21 章讨论执行基准和交易成本度量;实战派文献(Kissell, Glantz, Malamut; Berkowitz, Logue, Noser, 1988; Perold, 1988)有更多。
两个基准
VWAP = Volume-Weighted Average Price,成交量加权平均价:
其中 是 时刻的成交价, 是 时刻的成交量。它是这段时间里”市场平均参与者”实际拿到的价。对你的父单,同样水平期内你自己的成交均价是:
两者的差就是执行质量:
买入时正滑点意味着你付得比市场平均贵,卖出时正滑点意味着你拿得比市场平均少(符号习惯各家不同)。VWAP 算法就是试图把这个差压到零的算法:预测当天的日内成交量曲线,把父单切成子单、让累计成交跟着预测曲线走,每个区间发一笔。做到了,你的成交价就贴着市场 VWAP,相对平均参与者不多付也不少付。
TWAP = Time-Weighted Average Price,时间加权平均价,把成交量从定义里整个拿掉:
TWAP 算法相应地也简单粗暴:等大小的子单、等时间间隔地发。100 万股要在 4 个小时内出完,就是每小时 25 万股;按分钟切就是 240 笔等量子单,一分钟一笔。TWAP 不看成交量,只看钟。
为什么按成交量走通常更好
两者的差别在成交量分布不均匀的市场里立刻显形。股票的日内成交量典型长这样:
| 时段 | 占日成交量比例 |
|---|---|
| 开盘 (9:30) | 8% |
| 早盘 | 5% |
| 午盘 | 3% |
| 下午 | 4% |
| 收盘 (16:00) | 10% |
在这样的市场里跑 TWAP,你每小时机械地出 1/6.5 的量——于是你在成交量最稀薄的午盘大量成交,在成交量最厚的开盘和收盘反而欠成。跑 VWAP 则反过来:头 30 分钟出 8%、午盘只出 3%、尾盘出 10%,执行集中在流动性最深的时候。深流动性意味着两件事:每股冲击更小(量大 = 有人接),以及你不再是稀薄午盘流量里的大头、推动价格的风险更低。所以在普通日子里,VWAP 算法的执行成本一般低于 TWAP 算法——差多少取决于资产的成交量曲线有多不均匀和你的单有多大,别把任何一份 TCA 报告里的均值当常数用。
那 TWAP 为什么还活着
既然 VWAP 在期望上更好,TWAP 凭什么没被淘汰?三个诚实的理由。第一,它简单:不需要预测成交量,切完就发,出错的环节少。第二,有些市场根本没有可用的成交量数据——新上市的品种、薄交易的债券 ETF、某些山寨币,历史成交量模式要么不存在要么不可信,而 TWAP 对任何有报价的资产都能跑。第三,当你的真实约束是时间而不是成本——“这单必须在截止时间前匀速出完”——TWAP 的匀速本身就是你要的性质。
但要诚实就得把代价也摆出来:TWAP 的规律性是它最大的弱点。等间隔、等大小的子单是全市场最容易被识别的模式,这一点我们到失败方式三再细算。
VWAP 的前提:预测成交量
VWAP 算法的一切建立在一个预测上。标准方法是历史日内成交量分布:对每个资产,用过去 20–60 天的数据算出每个 5 分钟或 30 分钟桶平均占日成交量的比例,拿它当预测。一个简单模型:
其中 是桶 的历史平均成交量, 是预测的总日成交量——后者也得预测,常见做法从”等于昨天”到”最近 5 天或 20 天均值”再到按财报、宏观发布日调整,复杂度自选。实操上大多是混合方案:60 天历史平均做基础曲线,向最近的日子指数加权,事件日人工覆盖。更讲究的还会分情景(高波动、低波动、财报后、FOMC 日)备不同曲线,或者用市场总成交量加资产 beta 的横截面模型——但方法越花哨越容易把噪音当信号,基础款反而稳。
幸运的是,这个预测问题比大多数金融预测问题善良:日内成交量模式非常稳定。美股大盘股的 U 形——开盘高、午盘低、收盘高——是全球股票市场共同的规律:
日成交量按时间桶的比例(风格化示意)
9:30-10:00 ████████ 8%
10:00-11:00 ███ 3%
11:00-12:00 ██ 2.5%
12:00-13:00 ██ 2%
13:00-14:00 ██ 2.5%
14:00-15:00 ███ 3%
15:00-16:00 ████████ 9%
头 30 分钟加尾盘一小时合计约 17%,午盘四个小时合计才约 10%。加密的曲线平得多——比特币 24 小时交易,成交量在全天更均匀,美欧交易时段略有峰;期货的曲线则在开盘、宏观发布(CPI、FOMC)和收盘处有尖峰。算法必须适应资产各自的曲线,这也是前面那句话的另一面:均匀的 TWAP 对 U 形的股票成交量注定次优。Harris 第 21 章有讨论,Kissell 和 Glantz 的书覆盖实现细节。
四种失败方式
机制清楚了,回到开头的问题:这么谦虚的目标怎么还能搞砸?四种方式,一种比一种隐蔽。
第一种:你追的基准会被你们自己毁掉。 VWAP 算法的设计目标是贴住 VWAP,而当足够多的参与方都在跑 VWAP 算法时,他们全在同一时间按同一条成交量曲线成交——羊群。结果是日内成交量模式被进一步放大(开盘收盘相对午盘更突出),所有人的执行成本一起上升。这是个协调博弈:个体理性,整体次优。也正因为如此,一些机构客户干脆放弃 VWAP、改要 IS(implementation shortfall) 基准——IS 度量相对到达价(你决定交易那一刻的价格)的成本,不是相对平均价,算法没法靠跟别的算法扎堆来把它刷好看。
第二种:预测错了。 实际成交量偏离预测,你的 VWAP 算法就跟市场错位。预测太低,你相对实际流量出得太猛,自己推价格;预测太高,你出得太磨蹭、落后于节奏,最后在收盘附近把剩余规模匆匆砸出去、付高冲击——这个”尾盘赶工”是实践里最常见的死法。解药是把节奏做成自适应的:不锁死开盘定的时间表,日内根据实际成交量滚动调整,实际量跑在预测前面就加快、落后就放慢,目标从”贴住预测”换成”贴住实际的市场 VWAP”。在有意外的日子(宏观发布、财报意外、成交量尖峰)里,这一条是静态节奏和可用执行之间的分界线。
第三种:算法暴露了自己。 机械的算法——固定 5 分钟间隔、固定子单大小——在成交数据上留下的统计模式,检测起来并不难。一旦被识别,对手方(尤其是 HFT 做市商)就抢在你的下一笔子单前面成交,你为每一笔多付一点。这正是 TWAP 规律性的账单到期的地方。对策是往子单的大小和时机里注入随机性:每笔子单在节奏量的 80% 到 120% 之间浮动、发送带小随机延迟、市价单和被动限价单混着用。隐身不是免费的——你牺牲了节奏一致性,市场走势不利时可能更多地在坏价位成交——它买到的是更少的信息泄露。这笔账划不划算,取决于你的单有多大、多频繁,以及对手有多用心。
第四种:没有失败,但你本不该跑它。 VWAP 和 TWAP 都是被动基准,前提假设是你对未来价格没有看法。如果你有 alpha——你知道股票下一小时要涨——那么全天匀速买入就是把钱留在桌上:正确做法是前置成交、付高冲击、抓住 alpha。IS 基准和 IS 算法就是为这种流量生的:因为成本锚定在到达价上,IS 算法典型地开头激进、结尾被动。这不是 VWAP 的 bug,是适用范围的边界:无 alpha 的调仓、指数化流量用 VWAP,有 alpha 的流量用 IS。
何时用哪个
把上面的推理压成一张速查表:
| 情况 | 用 |
|---|---|
| 无 alpha,想最小化冲击 | VWAP |
| 无 alpha,成交量数据不可得 | TWAP |
| 有 alpha,想抓它 | IS |
| 订单相对日成交量很小 | VWAP 或市价单 |
| 大订单,必须今天完成 | VWAP 加上自适应 IS 叠加 |
| 订单必须匀速出到截止时间 | TWAP 加上截止时间强制 |
| 高度流动,预期低冲击 | VWAP |
| 不流动,难预测 | TWAP |
两点补充。其一,表里没有的情况:极不流动的名字上,任何节奏一致性都是幻觉,老老实实用小切片慢慢磨,别指望算法。其二,真正的硬时间压力(上午 11 点前必须完成)本质上是高紧急度问题,答案更接近前置的 IS 而不是任何被动节奏——匀速的 TWAP 只在”匀速本身就是需求”时才是答案。
最后一个提醒关于记分方式。“跑赢了 VWAP 2 bp”是一句信息量很低的话,因为 VWAP 滑点只是账单的一部分:日内价格朝你有利方向走时你没全抓到的机会成本、模式被检测造成的泄露、每笔子单付掉的半个价差、执行时机导致的账面与实现盈亏之差——这些都不在那 2 bp 里。完整的 TCA(交易成本分析)要把它们全摆上桌。永远对自己的执行跑 TCA;单看 VWAP 滑点会让一个昂贵的执行看起来很便宜。
Python 实现
节奏生成本身只有几行:
import numpy as np
import pandas as pd
def vwap_schedule(Q, forecast_volume, n_periods=13):
"""
按预测成交量曲线把父单 Q 切成 n_periods 段。
forecast_volume: 长度 n_periods 数组,每个周期的日成交量百分比。
返回:每个周期的子单大小数组。
"""
curve = np.array(forecast_volume) / np.sum(forecast_volume)
return Q * curve
# 玩具:买 100 万股,U 形成交量曲线
forecast = np.array([8, 3, 2.5, 2, 2.5, 3, 9]) # 7 个半小时周期
sizes = vwap_schedule(1_000_000, forecast, n_periods=7)
print(pd.Series(sizes, index=[f"period_{i}" for i in range(7)]).round(-2))
TWAP 就是把 forecast_volume 换成全 1。真正的工程量不在这几行里,而在它周围:成交量预测、自适应调整、随机化、TCA 回路。参数选择上的常识是:预测用 20–60 天历史(更老的数据未必反映当前模式);桶用 5 或 15 分钟(更细的桶更精确也更受噪音);TWAP 切片 12–60 笔(更多更平滑,也更可检测)。
出处订正与去处
最后交代一下文献脉络,因为这里有个常被搞混的地方。用 VWAP 做执行基准的思路出自 Berkowitz、Logue 和 Noser (1988) 对 NYSE 交易总成本的研究;而 implementation shortfall 的开创论文是 Perold (1988)——“纸面组合与真实组合之差”这个框架就是他提出的。两篇同年,各开一路:一路以市场平均价为锚,一路以决策时点价格为锚。这篇文章讲的四种失败方式,本质上就是从第一路的锚点缺陷一步步走到第二路的过程。工程化的成本估计和最优执行组合的框架,见 Kissell 和 Glantz 的《Optimal Trading Strategies》。
参考文献
- Harris, L. Trading and Exchanges: Market Microstructure for Practitioners. Oxford University Press, 2003. 第 21 章(流动性和交易成本度量)。ISBN: 978-0-19-514470-3.
- Berkowitz, S., Logue, D., Noser, J. “The Total Cost of Transactions on the NYSE.” Journal of Finance, 1988.
- Kissell, R., Glantz, M. Optimal Trading Strategies: Quantitative Approaches for Managing Market Impact and Trading Risk. AMACOM, 2003.
- Perold, A. “The Implementation Shortfall: Paper Versus Reality.” Journal of Portfolio Management, 1988.