第二章 TWAP算法数学原理:时间加权平均价格公式推导、切片逻辑与执行周期设计

好,咱们直接进入正题。

TWAP,全称 Time-Weighted Average Price,时间加权平均价格。名字听着挺唬人,但说白了,它的核心思想就一句话:把一个大单子,均匀地拆成小单子,在固定的时间窗口内分批执行。目标是什么?让我们的成交均价,尽量贴近这段时间的市场平均价。

我刚开始做量化交易那会儿,觉得这玩意儿太简单了,不就是平均分嘛。后来在实盘里吃过亏,才发现里面的门道比想象中深得多。今天我就把公式推导、切片逻辑和执行周期设计,掰开了揉碎了讲给你听。

2.1 时间加权平均价格的数学本质

先看公式。TWAP 的数学定义其实很朴素:

TWAP = (P₁ + P₂ + ... + Pₙ) / N

其中 P₁ 到 Pₙ 是每个时间点的价格,N 是时间点的总数。

你想想看,这个公式意味着什么?它假设我们在每个时间点都买入(或卖出)相同数量的股票。所以最终价格就是这些时间点价格的算术平均。

但这里有个坑——真实市场里,我们不可能在每个时间点都精确成交。我曾在一次 ETF 套利中,因为忽略了这一点,导致实际成交价和理论 TWAP 差了 3 个基点。嗯,3 个基点听起来不多,但资金量大的时候,够你心疼好一阵子的。

所以,更实用的公式是:

目标成交价 ≈ (∑ 每笔成交价 × 每笔成交量) / 总成交量

我们要做的,就是让这个实际成交均价,尽可能接近理论 TWAP。

核心要点:TWAP 不关心成交量分布,只关心时间分布。它假设市场在每个时间点都有足够的流动性来吃掉你的单子。

2.2 切片逻辑:把大象装进冰箱分几步?

切片,就是把总订单拆成若干个子订单。我习惯把切片逻辑分为三个层次:

  1. 时间切片:把总执行时间分成 N 个等长的时间段
  2. 数量切片:把总数量分成 N 等份
  3. 执行切片:在每个时间段内,把对应的数量发出去

举个例子。假设我们要买入 100 万股 ETF,执行时间 1 小时(3600 秒),切片数 N=12(每 5 分钟一个切片):

总数量 = 1,000,000 股
切片数 = 12
每片数量 = 1,000,000 / 12 ≈ 83,333 股
每片时长 = 3600 / 12 = 300 秒

代码实现起来也很直接:

def twap_slice(total_qty, total_seconds, num_slices):
    slice_qty = total_qty / num_slices
    slice_duration = total_seconds / num_slices
    
    schedule = []
    for i in range(num_slices):
        start_time = i * slice_duration
        end_time = (i + 1) * slice_duration
        schedule.append({
            'slice_id': i + 1,
            'start': start_time,
            'end': end_time,
            'qty': slice_qty
        })
    return schedule

# 调用示例
schedule = twap_slice(1000000, 3600, 12)
for s in schedule:
    print(f"切片{s['slice_id']}: {s['start']:.0f}s - {s['end']:.0f}s, 数量{s['qty']:.0f}股")

输出结果:

切片1: 0s - 300s, 数量83333股
切片2: 300s - 600s, 数量83333股
...
切片12: 3300s - 3600s, 数量83333股

个人经验:切片数 N 不是越大越好。我曾经把 N 设到 60(每 1 分钟一个切片),结果因为频繁发单,反而增加了冲击成本。后来我总结出一个经验:对于流动性好的 ETF,N 取 10-20 比较合适;流动性差的,N 取 5-10 就够了。

2.3 执行周期设计:从理论到实战的最后一公里

切片逻辑搞定了,接下来就是执行周期设计。这里我要重点讲三个东西:

2.3.1 周期类型

我一般把执行周期分为两种:

  • 固定周期:每个切片的时间长度完全相等。简单、好理解,但遇到市场剧烈波动时容易吃亏。
  • 动态周期:根据市场状态调整切片时长。比如波动率大的时候缩短切片,波动小的时候拉长切片。

我个人更倾向于动态周期。为什么?因为市场不是均匀的。你想想看,如果开盘前 5 分钟波动特别大,你还按固定周期慢慢发单,那不是等着被收割吗?

2.3.2 执行时机

每个切片内部,什么时候发单?这里有三种常见策略:

策略 说明 优缺点
切片开始时立即发单 一到时间点就发 简单,但容易造成价格冲击
切片中间点发单 在切片中间时刻发 能平滑一些,但时机不好把握
随机时间发单 在切片内随机选一个时间点发 能避免被对手盘识别,我比较推荐

我记得有一次做 ETF 套利,对手盘明显在盯着我的 TWAP 策略。我每次都在切片开始时发单,结果对方提前挂单等着吃我的货。后来改成随机时间发单,情况就好多了。

2.3.3 避坑指南

我曾经踩过的坑:

  • 切片数设太多,导致每片数量太小,被市场手续费吃掉利润
  • 没有考虑 ETF 的申赎机制,导致切片逻辑和申赎时间不匹配
  • 忽略了市场开盘和收盘的特殊时段,这两个时段波动大、流动性差

2.4 核心逻辑流程图

下面这张图,是我自己画的一个 TWAP 执行流程。你看一眼就能明白整个逻辑链条:

TWAP算法执行流程图 输入:总数量、总时间、切片数 计算:每片数量、每片时长 生成:切片时间表与数量表 循环:按切片计划逐片执行 执行完成 关键参数: • 切片数 N:10-20 • 每片时长:等分 • 每片数量:等分 执行策略: • 固定周期 • 动态周期 • 随机发单

2.5 实战中的几个关键点

最后,我再说几个实战中容易忽略的地方:

  • ETF 的最小交易单位:ETF 是 100 股一手,切片数量必须是 100 的整数倍。我见过有人直接除完就发单,结果被交易所拒单。
  • 市场冲击成本:切片数量太大,会推高价格;太小,又会被手续费吃掉。这个平衡点需要根据 ETF 的日均成交量来调整。
  • 时间同步:如果你的交易系统和交易所的时间不同步,切片逻辑就会乱套。我建议用 NTP 协议做时间同步,误差控制在 10 毫秒以内。

一句话总结:TWAP 的核心不是数学公式有多复杂,而是怎么把理论上的均匀分布,在真实市场里执行得既隐蔽又高效。切片逻辑是骨架,执行周期是血肉,两者缺一不可。

好了,这一章的内容就到这里。公式推导、切片逻辑、执行周期设计,这三个东西你吃透了,TWAP 就算入门了。下一章我们会聊更进阶的东西——怎么在 TWAP 里加入成交量权重,做成 VWAP。不过那是后话了,先把今天的内容消化掉。

专注资料整理