2、TWAP核心原理:时间切片机制、均匀分配逻辑、订单拆分策略

好,咱们直接进入正题。

TWAP,全称 Time-Weighted Average Price,时间加权平均价格。名字听着挺唬人,但说白了,它的核心思想就一句话:把一个大订单,切成很多小份,然后均匀地丢到市场里去

我最早接触 TWAP 是在做期货套利的时候。当时要建一个很大的头寸,一单下去市场直接打穿好几个价位。嗯,那感觉就像往平静的湖面扔了一块大石头。后来我才明白,真正专业的做法,是像下雨一样,细密而均匀。

2.1 时间切片机制:把时间切成豆腐块

时间切片,是 TWAP 最底层的逻辑。你想想看,如果给你 1 个小时,要买 100 万股。你会怎么做?

我个人的习惯是,先把这 1 小时切成 N 个等长的时间片。比如切成 60 片,每片 1 分钟。或者切成 120 片,每片 30 秒。这个切片的过程,就是时间切片机制。

核心公式:
时间片长度 = 总执行时间 / 切片数量
每个时间片的目标成交量 = 总订单量 / 切片数量

这里有个关键点:切片数量怎么定?

  • 切片太少:比如只切 10 片,每片 6 分钟。那每片的订单量还是很大,依然会冲击市场。说白了,失去了拆单的意义。
  • 切片太多:比如切 600 片,每片 6 秒。理论上更均匀,但实际中,每片可能只成交几股,频繁的撤单和挂单反而会增加交易成本。

我在项目中遇到过一种情况:某次做港股交易,流动性很差。我一开始切了 60 片,结果发现很多时间片根本成交不了。后来我改成 20 片,每片 3 分钟,反而效果更好。所以,切片数量要结合市场流动性来调整,没有绝对的标准。

2.2 均匀分配逻辑:别让市场猜到你的底牌

均匀分配,是 TWAP 的灵魂。它的目标很简单:让每一段时间内的交易量,都差不多

为什么会这样?因为如果你在某一段时间内突然加大交易量,市场就会察觉到异常。做市商和算法交易系统会立刻捕捉到你的意图,然后反向操作,让你买在最高点,卖在最低点。

均匀分配的逻辑,通常有两种实现方式:

  1. 固定数量法:每个时间片分配完全相等的股数。比如总订单 100 万股,切 100 片,每片就是 1 万股。这是最朴素的做法。
  2. 固定比例法:根据历史成交量分布,调整每个时间片的分配比例。比如开盘和收盘时段流动性好,就多分配一些;午盘流动性差,就少分配一些。
我的建议: 新手先用固定数量法。简单、透明、容易 debug。等跑通了,再考虑引入成交量分布模型做优化。

这里有一个常见的误区:均匀分配 ≠ 机械执行。你想想看,如果市场突然出现一个巨大的卖单,价格瞬间砸下去 2%。这时候你还按原计划均匀买入吗?当然不。这时候应该暂停一下,或者加速买入。所以,真正的 TWAP 算法,会在均匀分配的基础上,加入一些动态调整的逻辑。

2.3 订单拆分策略:从大单到小单的艺术

订单拆分,是 TWAP 落地的最后一步。前面我们切好了时间片,算好了每片的量,现在要做的就是:把每片的订单,拆成更小的子订单,然后发到交易所

拆分的策略,我总结为三种:

策略名称 做法 适用场景
单笔全量 每个时间片只发一笔订单,数量等于该片的目标量 流动性极好、市场深度足够的品种
多笔均分 每个时间片再拆成 3-5 笔,每笔数量相等 大多数主流股票、期货
随机拆分 每个时间片拆成多笔,每笔数量在一定范围内随机 需要隐藏交易意图、防止被识别的场景

我个人最常用的是多笔均分。为什么呢?因为单笔全量太容易被看穿,随机拆分又太复杂,不好控制。多笔均分,既分散了风险,又保持了逻辑的简洁。

我曾经踩过的坑: 有一次做美股交易,我用了随机拆分策略。结果因为随机范围设得太大,导致某几笔订单数量特别小,被交易所当成垃圾订单给拒了。后来我学乖了,随机范围控制在 ±20% 以内,既达到了隐藏意图的目的,又不会触发风控。

另外,订单拆分时还要考虑一个细节:限价单 vs 市价单。TWAP 通常使用限价单,因为市价单的成本不可控。限价单的价格怎么设?一般是在当前买一价或卖一价的基础上,加一个偏移量。这个偏移量,我习惯设为 1-2 个 tick,既能保证成交概率,又不会吃太大的滑点。

2.4 核心逻辑流程图

下面这张图,是我自己画的一个 TWAP 核心逻辑流程图。你可以把它当作一个速查表,写代码的时候对照着看。

TWAP 核心执行流程图 接收大订单 步骤1:时间切片 将总执行时间切为 N 个等长的时间片 步骤2:均匀分配 计算每个时间片的目标成交量 步骤3:订单拆分 将每片订单拆为多笔子订单并发送 执行完成

这张图看起来很简单,但每一个步骤背后都有很多细节。比如步骤1中,切片数量怎么定?步骤2中,均匀分配要不要考虑成交量分布?步骤3中,限价单的价格怎么设?这些我们在后面的章节中会逐一展开。

2.5 一个简单的代码示例

光说不练假把式。下面我写一个极简的 TWAP 核心逻辑,用 Python 实现。注意,这只是教学演示,生产环境要复杂得多。

class SimpleTWAP:
    def __init__(self, total_qty, total_seconds, num_slices):
        self.total_qty = total_qty          # 总订单量
        self.total_seconds = total_seconds  # 总执行时间(秒)
        self.num_slices = num_slices        # 切片数量
        self.slice_seconds = total_seconds / num_slices  # 每片时长
        self.slice_qty = total_qty / num_slices          # 每片目标量
    
    def generate_schedule(self):
        """生成执行计划"""
        schedule = []
        for i in range(self.num_slices):
            start_time = i * self.slice_seconds
            end_time = (i + 1) * self.slice_seconds
            schedule.append({
                'slice_id': i,
                'start': start_time,
                'end': end_time,
                'target_qty': self.slice_qty
            })
        return schedule
    
    def split_order(self, slice_qty, num_sub_orders=3):
        """将每片的订单拆成多笔"""
        sub_qty = slice_qty / num_sub_orders
        orders = []
        for j in range(num_sub_orders):
            orders.append({
                'sub_id': j,
                'qty': sub_qty,
                'price': 'LIMIT'  # 实际中需要计算具体价格
            })
        return orders

# 使用示例
twap = SimpleTWAP(total_qty=100000, total_seconds=3600, num_slices=60)
schedule = twap.generate_schedule()
print(f"共 {len(schedule)} 个时间片,每片目标量 {schedule[0]['target_qty']:.0f} 股")
# 输出:共 60 个时间片,每片目标量 1667 股

这段代码虽然简单,但已经包含了 TWAP 的三个核心要素:时间切片、均匀分配、订单拆分。你可以在它的基础上,加入动态调整、风控检查、日志记录等功能。

一个小技巧: 在实际开发中,我习惯把时间片的状态记录下来,比如「已发送」「已成交」「部分成交」「超时未成交」。这样方便做异常处理和事后复盘。

好了,这一章的内容就到这里。TWAP 的核心原理其实不复杂,难的是在真实市场中把它跑稳、跑好。下一章我们会聊到 TWAP 的实战参数调优,到时候我会分享一些具体的调参经验和踩坑记录。


公众号:蓝海资料掘金营,微信deep3321