第二章:仿真策略开发——基于订单簿的做市信号生成、库存管理模型、最优报价算法实现

做市策略从仿真到实盘,最核心的一步就是策略本身的开发。说实话,很多新手一上来就想着怎么赚钱,忽略了策略的底层逻辑。我个人习惯是先把三个模块拆开看:信号怎么来、库存怎么管、价格怎么报。这三个东西搞定了,策略骨架就有了。

2.1 基于订单簿的做市信号生成

做市信号说白了就是告诉你——现在该不该报价,往哪边报。订单簿(Order Book)是我们最直接的信号源。我在项目中遇到过不少团队,拿着Tick数据一顿算,结果信号滞后严重。其实你想想看,订单簿的实时变化才是做市商的第一手情报。

2.1.1 订单簿特征提取

我们通常从订单簿中提取以下几类特征:

  • 买卖价差(Spread):卖一价减去买一价。价差越小,流动性越好,做市利润空间越薄。
  • 订单簿深度(Depth):买一到买五、卖一到卖五的挂单量。深度越大,价格越难被推动。
  • 订单簿不平衡(Order Book Imbalance, OBI):买盘总量与卖盘总量的比值。OBI > 1 说明买盘强,价格可能上涨。
  • 加权中间价(Weighted Mid Price):按挂单量加权计算的真实中间价,比简单中间价更敏感。

核心公式:

OBI = (买盘总量) / (买盘总量 + 卖盘总量)

加权中间价 = (买一价 * 卖一量 + 卖一价 * 买一量) / (买一量 + 卖一量)

2.1.2 信号生成逻辑

我个人习惯用OBI作为主信号。举个例子:

def generate_signal(ob):
    bid_vol = sum(ob.bids[i].volume for i in range(5))
    ask_vol = sum(ob.asks[i].volume for i in range(5))
    obi = bid_vol / (bid_vol + ask_vol)
    
    if obi > 0.65:
        return 'BUY_BIAS'   # 偏向买入,报价上移
    elif obi < 0.35:
        return 'SELL_BIAS'  # 偏向卖出,报价下移
    else:
        return 'NEUTRAL'    # 中性,对称报价

嗯,这里要注意:阈值0.65和0.35不是固定的。我在实盘中会根据波动率动态调整。波动率大的时候,阈值要放宽,不然信号太频繁,容易来回打脸。

2.2 库存管理模型

做市商最怕什么?库存积压。你想想看,手里囤了一堆货,价格一跌,账面亏损就来了。库存管理的目标就是让库存水平始终围绕目标值(通常是0)波动。

2.2.1 库存风险度量

我们用一个简单的指标来衡量库存风险:

指标 公式 说明
库存偏离度 (当前库存 - 目标库存) / 最大容忍库存 偏离越大,风险越高
库存价值风险 库存量 * 波动率 * 持有时间 衡量潜在亏损

2.2.2 库存管理策略

我常用的库存管理策略有两种:

  1. 偏移报价法:库存偏离目标时,主动调整报价偏移量。比如库存为正(手里有货),就降低卖价、提高买价,鼓励卖出、抑制买入。
  2. 对冲平仓法:库存超过阈值时,直接下市价单平仓。这种方法比较激进,适合波动率高的品种。

避坑指南:我曾经在仿真阶段把库存阈值设得太小,结果策略频繁平仓,手续费吃掉了一大半利润。后来我把阈值放宽到最大容忍库存的70%,效果好了很多。记住,仿真阶段要多试几组参数。

2.3 最优报价算法实现

信号有了,库存管住了,接下来就是报价。最优报价算法的核心是:在保证成交概率的前提下,最大化期望收益。

2.3.1 报价偏移模型

我们基于Avellaneda-Stoikov模型做简化。报价偏移量由两部分组成:

  • 库存偏移:库存偏离越大,报价偏移越大。公式:偏移量 = -γ * 库存量 * 波动率
  • 信号偏移:根据OBI信号调整。买入信号时,买卖报价同时上移;卖出信号时,同时下移。
def calculate_quote(mid_price, inventory, volatility, signal):
    # 库存偏移
    inv_skew = -0.1 * inventory * volatility
    
    # 信号偏移
    if signal == 'BUY_BIAS':
        sig_skew = 0.05 * volatility
    elif signal == 'SELL_BIAS':
        sig_skew = -0.05 * volatility
    else:
        sig_skew = 0.0
    
    total_skew = inv_skew + sig_skew
    
    bid_price = mid_price + total_skew - spread/2
    ask_price = mid_price + total_skew + spread/2
    
    return bid_price, ask_price

2.3.2 报价宽度调整

报价宽度(即买卖价差)也不是固定的。我建议根据订单簿深度动态调整:

订单簿深度 报价宽度 逻辑
深度大(流动性好) 缩小价差 竞争激烈,薄利多销
深度小(流动性差) 扩大价差 风险高,利润要厚

注意:报价宽度不能无限缩小。最低价差要覆盖手续费和滑点成本。我一般设置一个底线,比如最小价差 = 2 * 手续费率 * 价格。

2.4 整体策略框架图

下面我用一张SVG图来展示这三个模块的关系。你可以看到,信号生成、库存管理、报价算法是闭环运作的。

做市策略核心模块流程图 订单簿数据输入 信号生成模块 OBI计算 | 波动率估计 | 信号分类 库存管理模块 库存偏离度 | 偏移计算 最优报价算法 报价偏移 | 宽度调整 买卖报价输出

这张图你看懂了吗?订单簿数据进来后,信号生成模块先判断方向,库存管理模块算偏移量,最后报价算法把两者合并,输出最终的买卖报价。三个模块缺一不可。

2.5 仿真测试要点

策略写完了,别急着上实盘。仿真阶段有几个坑,我帮你列出来:

  • 回测数据要够长:至少包含3个月的数据,覆盖不同市场状态(趋势、震荡、高波动)。
  • 考虑滑点和手续费:很多仿真跑出来很漂亮,一加上滑点就亏。我习惯在仿真中加一个保守的滑点模型。
  • 压力测试:模拟极端行情,比如瞬间大单砸盘,看看你的库存管理能不能扛住。

个人经验:我刚开始做仿真时,总想着参数调得越精细越好。后来发现,过度拟合历史数据反而在实盘上表现很差。仿真阶段更重要的是验证逻辑的鲁棒性,而不是追求回测曲线好看。

好了,这一章的内容就到这里。信号生成、库存管理、报价算法,这三个模块你可以在仿真环境中反复调试。记住,仿真阶段多花时间,实盘阶段少交学费。


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