3、冰山订单的算法框架:时间切片模型、成交量加权模型、动态调整模型

聊到冰山订单的算法实现,我脑子里第一个蹦出来的画面,是几年前在实盘环境里调试一个高频做市策略。当时订单簿上明明挂着大单,可一吃就没了——后来才发现,那是别人的冰山订单在“钓鱼”。

说白了,冰山订单的核心就一句话:把一个大单拆成无数个小单,分批扔进市场。但怎么拆、什么时候扔、扔多少,这里面的门道就深了。

我个人习惯把冰山订单的算法框架分成三大流派:时间切片模型成交量加权模型动态调整模型。咱们一个一个拆开看。

3.1 时间切片模型:最简单的“定时定量”

这个模型最直观。你想想看,我要卖100万股,不想让人看出来。那就把时间切成N段,每段扔固定数量的单子。

比如,交易时段是4小时(240分钟),我切成240个1分钟切片。每分钟扔4167股。嗯,就这么简单。

代码实现大概长这样:

class TimeSliceIceberg:
    def __init__(self, total_qty, total_time, slices):
        self.total_qty = total_qty
        self.slice_qty = total_qty // slices
        self.interval = total_time / slices
        self.remaining = total_qty
        
    def next_order(self, current_time):
        # 计算当前应该在第几个切片
        slice_idx = int(current_time / self.interval)
        if slice_idx * self.slice_qty <= self.remaining:
            return min(self.slice_qty, self.remaining)
        return 0

优点:实现简单,逻辑清晰,回测时几乎不会出bug。

缺点:太死板了。市场在暴涨,你还在按部就班地卖;市场在暴跌,你还在傻乎乎地买。我曾经在一个震荡市里用这个模型,结果被来回打脸——每次都在最不利的价位成交。

⚠️ 避坑指南:时间切片模型只适合流动性极好、波动极小的品种。比如国债期货、大型蓝筹股。别拿它去搞小盘股,你会后悔的。

3.2 成交量加权模型:跟着市场节奏走

这个模型就聪明多了。它不按时间切,而是按市场成交量来切。

核心逻辑是:市场成交了多少,我就跟着成交多少。比如,我设定一个参与率参数α=0.05,意思是市场每成交100股,我就成交5股。

公式很简单:

当前应成交量 = 市场累计成交量 × α - 已成交量

代码实现:

class VolumeWeightedIceberg:
    def __init__(self, total_qty, participation_rate):
        self.total_qty = total_qty
        self.alpha = participation_rate  # 参与率
        self.executed = 0
        
    def next_order(self, market_volume):
        target = int(market_volume * self.alpha)
        order_qty = target - self.executed
        if order_qty > 0:
            order_qty = min(order_qty, self.total_qty - self.executed)
            self.executed += order_qty
            return order_qty
        return 0

这个模型的好处是:市场活跃时我多交易,市场冷清时我少交易。不会在流动性枯竭的时候硬往里冲。

我记得有一次做港股交易,下午3点半之后流动性骤降。如果用时间切片模型,我还在那硬挂单,结果被做市商吃得死死的。换成成交量加权模型后,自动减少了交易频率,成本降了将近30%。

💡 个人经验:α参数的设置很关键。一般建议在0.01到0.1之间。太小了完成不了任务,太大了容易被发现。我习惯先跑一周的历史数据,找到最优α值。

3.3 动态调整模型:真正的“智能冰山”

前两个模型都是静态的——参数设好了就不变了。但市场是活的,你的算法也得是活的。

动态调整模型的核心思想是:根据市场状态实时调整下单策略。它会考虑三个维度:

  • 价格偏离度:当前价格离我的目标价有多远
  • 订单簿深度:买卖挂单的厚度如何
  • 市场冲击成本:我每下一单,价格会滑多少

我设计过一个简单的动态调整模型,核心逻辑是:

class DynamicIceberg:
    def __init__(self, total_qty, target_price):
        self.total_qty = total_qty
        self.target_price = target_price
        self.executed = 0
        
    def calc_order_size(self, current_price, bid_depth, ask_depth):
        # 价格偏离度越大,下单越保守
        price_dev = abs(current_price - self.target_price) / self.target_price
        
        # 订单簿越薄,下单越小
        liquidity = (bid_depth + ask_depth) / 2
        
        # 动态调整下单量
        base_qty = self.total_qty // 100
        adjust_factor = max(0.1, 1 - price_dev * 10)
        liquidity_factor = min(1, liquidity / 100000)
        
        order_qty = int(base_qty * adjust_factor * liquidity_factor)
        return min(order_qty, self.total_qty - self.executed)

这个模型的好处是:市场对你有利时,你加速交易;市场对你不利时,你减速甚至暂停

我曾经在实盘中遇到过这种情况:一个大单刚挂出去,价格突然跳水。动态调整模型立刻检测到价格偏离度超过阈值,自动把下单量降到了原来的10%。等价格反弹回来,再恢复正常的交易节奏。这一波操作,帮我少亏了至少50个基点。

三种模型对比总结

模型 核心逻辑 适用场景 风险点
时间切片 固定时间间隔下单 高流动性、低波动 市场突变时失效
成交量加权 按市场成交量比例下单 中等流动性 参数α难调优
动态调整 多因子实时决策 所有场景 实现复杂、过拟合风险

下面这张图,是我自己画的一个冰山订单算法框架图,帮你理清这三种模型的关系:

冰山订单算法框架 冰山订单算法 时间切片模型 成交量加权模型 动态调整模型 固定间隔 固定数量 简单易实现 参与率α 跟随市场 流动性自适应 多因子决策 实时调整 智能风控 核心目标:隐藏大单意图,降低冲击成本 从简单到复杂,从静态到动态

最后说一句,这三种模型没有绝对的好坏。我个人的建议是:从时间切片模型开始,跑通整个流程;然后升级到成交量加权模型,优化执行成本;最后再上动态调整模型,追求极致表现。一步到位搞动态调整,很容易掉进过拟合的坑里。

避坑指南:我曾经在一个项目里,一上来就搞动态调整模型,用了十几个因子。结果回测曲线漂亮得不行,实盘一跑就崩。后来才发现,那些因子在回测里是“伪相关”,实盘里根本没用。所以,先做减法,再做加法


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