3. 时间加权平均价格算法(TWAP)
TWAP,全称 Time-Weighted Average Price。说白了,就是把一个大单子,均匀地拆成很多小单子,在固定的时间段内分批执行。
我刚开始做高频交易那会儿,觉得这算法太简单了。不就是把100万股拆成100份,每分钟扔1万股嘛。后来才发现,越简单的东西,坑越多。
3.1 TWAP原理
TWAP的核心思想就一句话:让成交价格尽可能接近这段时间的平均价。
它的数学表达很简单:
TWAP = (P1 + P2 + ... + Pn) / n
其中P1到Pn是每个时间点的价格。我们的目标,就是让实际成交价尽量贴近这个值。
具体怎么做呢?
- 把交易时间分成N个等长的时间片
- 每个时间片内,只交易总订单量的1/N
- 时间片内再按市场流动性做微调
举个例子。假设我要在10分钟内买入100万股。我会这样做:
- 把10分钟分成10个1分钟的时间片
- 每个时间片只交易10万股
- 这10万股再根据盘口深度,拆成更小的单子
嗯,这里要注意。时间片怎么切,其实很有讲究。我见过有人用固定1秒一片,也有人用动态切片。我个人习惯用5-10秒一片,太短了容易暴露意图,太长了又跟不上行情变化。
3.2 TWAP实现
来,直接上代码。这是我实际项目中用过的简化版本:
class TWAPExecutor:
def __init__(self, total_qty, start_time, end_time, slices=20):
self.total_qty = total_qty # 总交易量
self.start_time = start_time # 开始时间
self.end_time = end_time # 结束时间
self.slices = slices # 切片数
self.qty_per_slice = total_qty / slices
def generate_schedule(self):
"""生成交易时间表"""
interval = (self.end_time - self.start_time) / self.slices
schedule = []
for i in range(self.slices):
slice_time = self.start_time + interval * i
schedule.append({
'time': slice_time,
'qty': self.qty_per_slice,
'status': 'pending'
})
return schedule
def execute_slice(self, slice_info):
"""执行单个时间片的交易"""
# 这里根据盘口深度再拆分子单
sub_orders = self._split_by_liquidity(
slice_info['qty'],
self._get_order_book()
)
for sub in sub_orders:
self._place_order(sub)
def _split_by_liquidity(self, qty, order_book):
"""根据流动性拆分子单"""
# 我习惯控制在盘口总量的5%以内
max_per_order = order_book['bid_size'] * 0.05
sub_qty = min(qty, max_per_order)
return [{'qty': sub_qty}] * int(qty / sub_qty)
这段代码看起来简单,但实际跑起来问题不少。我曾经在实盘中发现,如果市场突然没流动性了,这个算法还在傻傻地往外扔单子,结果就是滑点大得吓人。
3.3 TWAP优缺点
任何算法都有两面性。TWAP也不例外。
| 优点 | 缺点 |
|---|---|
| 实现简单,逻辑清晰 | 完全不考虑市场波动 |
| 执行成本可预测 | 遇到大行情容易吃亏 |
| 适合大单拆分 | 容易被对手盘识别 |
| 监管合规性好 | 无法捕捉有利时机 |
你想想看,TWAP最大的问题是什么?它太机械了。市场在涨,它还在卖;市场在跌,它还在买。说白了,它就是个没有感情的机器人。
我记得有一次做回测,用TWAP跑一个月的交易数据。结果发现,在趋势行情里,TWAP的表现远不如VWAP。为什么?因为TWAP不关心成交量分布,而趋势行情里成交量往往集中在某个时段。
3.4 TWAP适用场景
那么,什么时候该用TWAP呢?我总结了几种情况:
- 低波动市场: 市场波动小的时候,TWAP的机械性反而成了优势
- 流动性充足: 大盘股、主流币种,随便拆都不会影响价格
- 被动执行: 不追求alpha,只求完成交易
- 测试阶段: 新策略上线前,用TWAP做基准测试
反过来,什么时候千万别用?
- 重大新闻发布前后
- 开盘和收盘的集合竞价阶段
- 流动性极差的小盘股
- 需要抢跑的高频策略
我个人习惯,在实盘前先用TWAP跑一周的模拟盘。不是为了赚钱,而是为了摸清市场的脾气。等摸透了,再上更复杂的算法。
最后说一句。TWAP虽然简单,但它是所有拆分算法的基础。你把它吃透了,后面学VWAP、POV、Implementation Shortfall都会轻松很多。别小看它。