一、交易策略与冲击成本:大单拆分策略、冰山订单、TWAP/VWAP算法执行

做量化交易这些年,我见过太多人一上来就问「怎么选策略」。其实吧,选策略之前,你得先搞清楚一个更底层的问题——你的订单是怎么进场的。

尤其是大单。你想想看,一个几百万的买单砸进去,市场瞬间就变了脸。价格被推高,你的成交成本直线上升。这就是冲击成本,说白了就是「你的交易行为本身影响了价格」。

我个人习惯把冲击成本分成两块:永久性冲击暂时性冲击。永久性冲击是市场真的被你的单子改变了供需关系,价格回不去了。暂时性冲击呢,是流动性被瞬间抽走,等市场缓过来,价格还能回来一些。

嗯,这里要注意——我们做算法交易,核心目标就是在控制冲击成本的前提下,尽快完成交易。这两个目标是矛盾的,所以需要各种拆分策略来平衡。

1.1 大单拆分策略:把大象装进冰箱

大单拆分,说白了就是把一个大订单切成很多小单,分批进场。我刚开始做的时候,觉得这有什么难的?直接均分不就完了?后来发现,事情远没那么简单。

拆分的核心逻辑是:用小单的「隐蔽性」换取大单的「执行效率」。你每次只吃一小口,市场不容易察觉,价格就不会被推得太高。

常见的拆分方式有几种:

  • 等量拆分:每批下单数量相同。简单粗暴,但容易在流动性不足时暴露意图。
  • 等时拆分:固定时间间隔下单。适合流动性稳定的品种。
  • 动态拆分:根据市场实时流动性调整每批大小。这个最灵活,但也最考验算法能力。

我在项目中遇到过一个大坑——用等量拆分做股指期货,结果在开盘瞬间流动性骤降,我的单子直接把价格打穿了。后来我改成动态拆分,根据盘口深度实时调整每批数量,情况就好多了。

核心原则:拆分不是越细越好。太细了,交易次数太多,手续费和延迟成本反而会吃掉你的收益。我一般建议每批订单控制在总流动性的1%-3%之间。

1.2 冰山订单:藏在水面下的真实意图

冰山订单这个名字很形象——你只看到水面上的一小块冰,但水面下藏着巨大的体积。

具体来说,冰山订单会显示一个「可见量」,比如100手。当这100手被吃掉后,系统会自动再挂出100手,直到全部成交。市场参与者看到的始终只有100手,不知道你实际要买10000手。

为什么要用冰山订单?

  • 隐藏真实意图:避免被其他交易者「盯上」
  • 减少冲击成本:每次只暴露一小部分,价格不会剧烈波动
  • 延长执行时间:给市场时间消化你的订单

我曾经用冰山订单做一只小盘股的建仓。那股票流动性很差,日成交额才几千万。如果用普通限价单,挂个几十万就把价格拉起来3%。用冰山订单后,每次只露5000股,花了整整两天才建完仓,但冲击成本降低了将近60%。

注意:冰山订单不是万能的。在流动性极差的市场,或者遇到高频交易者「钓鱼」时,你的冰山订单可能会被反复试探。我见过有人用冰山订单被高频交易者「剥头皮」,每次刚挂出来就被吃掉,然后价格立刻回落,反复几次,成本反而更高了。

1.3 TWAP算法:时间加权平均价格

TWAP,全称Time-Weighted Average Price,时间加权平均价格。它的逻辑很简单:把交易时间均匀分割,在每个时间片内执行固定比例的单量

举个例子,你要在1小时内买入100万股,TWAP会把它切成60个1分钟的时间片,每个时间片买入约16667股。不管市场怎么波动,都按这个节奏走。

TWAP的优点:

  • 执行节奏稳定,容易预测
  • 实现简单,代码量小
  • 适合流动性充足、波动不大的品种

TWAP的缺点也很明显:

  • 完全不考虑市场状况
  • 在趋势行情中表现很差——如果价格一直在涨,你还在匀速买入,成本会越来越高

我个人的习惯是,TWAP只用在盘后对冲或者流动性极好的品种上。比如做ETF套利时,用TWAP来调整仓位,效果还不错。

下面是一个简单的TWAP实现示例:

def twap_executor(total_qty, total_seconds, interval_seconds=60):
    """
    TWAP算法执行器
    :param total_qty: 总交易量
    :param total_seconds: 总执行时间(秒)
    :param interval_seconds: 每个时间片长度(秒)
    """
    num_slices = total_seconds // interval_seconds
    qty_per_slice = total_qty // num_slices
    
    for i in range(num_slices):
        # 每个时间片下单
        place_order(qty=qty_per_slice)
        # 等待下一个时间片
        sleep(interval_seconds)
    
    # 处理剩余零头
    remaining = total_qty - qty_per_slice * num_slices
    if remaining > 0:
        place_order(qty=remaining)

1.4 VWAP算法:成交量加权平均价格

VWAP,全称Volume-Weighted Average Price,成交量加权平均价格。这个比TWAP聪明一点——它根据历史成交量分布来分配下单节奏

为什么这么做?因为市场成交量不是均匀分布的。开盘和收盘通常成交量最大,中午休息时间成交量最小。如果你在成交量小的时候下大单,冲击成本会很高。

VWAP的做法是:先统计过去N天的成交量分布,然后按照这个分布来分配今天的下单量。比如过去数据显示,9:30-9:35这5分钟的成交量占全天5%,那VWAP就会在这个时间段下5%的单量。

VWAP的优点:

  • 更贴合市场实际流动性
  • 冲击成本通常比TWAP低
  • 执行价格接近市场均价

VWAP的缺点:

  • 依赖历史数据,如果今天成交量分布异常,效果会变差
  • 实现比TWAP复杂一些

我记得有一次做股指期货的VWAP执行,那天突然出了个重大利好,开盘后成交量暴增。我的VWAP算法按照历史分布来下单,结果在开盘阶段下单量不足,后面成交量回落时反而下了很多单,成本比预期高了不少。从那以后,我就在VWAP里加了一个实时成交量修正因子,根据当前实际成交量动态调整分配比例。

实战技巧:我建议把TWAP和VWAP结合起来用。比如用VWAP确定每个时间片的下单比例,再用TWAP在时间片内均匀执行。这样既考虑了成交量分布,又保持了执行节奏的稳定性。

1.5 三种策略的对比与选择

说了这么多,到底什么时候用哪种?我整理了一个对比表:

策略 适用场景 优点 缺点
冰山订单 流动性差、需要隐藏意图 隐蔽性强,冲击成本低 执行时间长,可能被钓鱼
TWAP 流动性好、波动小、盘后对冲 简单稳定,容易预测 不考虑市场状况,趋势行情差
VWAP 追求市场均价、大单执行 贴合流动性,成本可控 依赖历史数据,异常行情失效

我个人建议:没有最好的策略,只有最合适的策略。你需要根据品种的流动性、你的交易目标、市场状况来灵活选择。甚至可以在同一个交易中混合使用多种策略——比如先用冰山订单建底仓,再用VWAP完成剩余部分。

1.6 核心知识体系

下面这张图是我自己画的,把本章的核心逻辑串起来了:

交易策略与冲击成本核心逻辑 冲击成本控制 大单拆分策略 冰山订单 算法执行 等量拆分 等时拆分 动态拆分 隐藏意图 减少冲击 TWAP VWAP 混合策略 核心目标:在控制冲击成本的前提下,尽快完成交易 没有最好的策略,只有最合适的策略

这张图把本章的核心逻辑串起来了。从冲击成本控制出发,衍生出三大类策略,每类策略又有不同的实现方式。你可以在实际交易中根据情况灵活组合。

一句话总结:大单拆分是基础,冰山订单是技巧,TWAP/VWAP是工具。三者结合,才能把冲击成本降到最低。