第三章:做市策略核心:存货风险模型、Avellaneda-Stoikov模型、报价宽度与报价水平的确定、最优报价策略

3.1 存货风险模型——做市商的头号敌人

做市商最怕什么?不是行情暴跌,而是手里积了一堆卖不掉的货。

我刚开始做高频做市那会儿,有次在ETH-USDT上挂了大量买单。行情突然跳水,我的库存瞬间从50个ETH变成了800个。账面浮亏不说,关键是流动性枯竭了,想平仓都平不掉。那晚我盯着屏幕,看着库存数字发呆——这就是典型的存货风险。

存货风险模型,说白了就是量化「库存太多」带来的损失。核心公式很简单:

存货风险 = 库存量 × 价格波动率 × 时间因子

但实际落地时,要考虑三个维度:

  • 库存偏离度:当前库存与目标库存的差值。目标库存通常是0,但有些策略会保留一定底仓。
  • 波动率调整:波动越大,存货风险越高。我习惯用5分钟滚动波动率,而不是日波动率——做市是毫秒级的,用日数据太滞后。
  • 时间衰减:库存持有时间越长,风险越大。因为市场可能在你持仓期间发生不利变动。

核心观点:存货风险不是静态的,它是动态变化的。你每成交一笔,风险就变一次。

3.2 Avellaneda-Stoikov模型——做市策略的数学基石

这个模型是我个人最喜欢的做市理论框架。它由Marco Avellaneda和Sasha Stoikov在2008年提出,虽然已经十几年了,但至今仍是高频做市策略的标配。

模型的核心思想是:做市商应该根据库存水平动态调整报价。库存多了就降价卖,库存少了就提价买。

公式长这样:

最优报价偏移 = -γ × σ² × (T - t) × q

其中:

  • γ:风险厌恶系数。我一般设0.1-0.5,取决于市场波动。
  • σ:波动率。用高频数据算,比如1分钟收益率的标准差。
  • T - t:剩余时间。做市周期通常设5-30分钟。
  • q:当前库存量。正数表示多头,负数表示空头。

举个例子:假设γ=0.2,σ=0.01,T-t=10分钟,q=100个ETH。那么报价偏移 = -0.2 × 0.0001 × 600 × 100 = -1.2。也就是说,你的卖价要比中间价低1.2个tick。

实战技巧:我建议把γ设成动态的。波动大的时候调高γ,波动小的时候调低。这样能自适应市场环境。

3.3 报价宽度与报价水平的确定

报价宽度就是买卖价差。太宽了成交少,太窄了赚不到钱。怎么平衡?

我总结了一个经验公式:

最优价差 = 基础价差 + 库存调整项 + 波动率调整项

基础价差通常取市场平均价差的1.2倍。库存调整项用Avellaneda-Stoikov模型的偏移量。波动率调整项则是:波动率越高,价差越大。

报价水平呢?就是你的买价和卖价具体定在哪。我习惯用「对称偏移」法:

  • 买价 = 中间价 - 价差/2 - 库存偏移
  • 卖价 = 中间价 + 价差/2 - 库存偏移

注意看,库存偏移对买卖双方的影响是相反的。库存多的时候,买价要更低(减少买入),卖价也要更低(促进卖出)。

避坑指南:我曾经犯过一个错误——把库存偏移直接加到买卖价上,结果两边都偏移了同一个方向。那天的成交记录简直惨不忍睹,一边狂成交一边完全没单。后来才意识到,偏移量对买卖方向是相反的。

3.4 最优报价策略——把理论变成代码

理论讲完了,咱们看看怎么落地。下面是我常用的一个简化版最优报价策略:

def optimal_quote(mid_price, inventory, volatility, gamma=0.3, horizon=600):
    """
    计算最优报价
    :param mid_price: 当前中间价
    :param inventory: 当前库存(正数多头,负数空头)
    :param volatility: 波动率
    :param gamma: 风险厌恶系数
    :param horizon: 做市周期(秒)
    """
    # 计算库存偏移
    inventory_shift = -gamma * (volatility ** 2) * horizon * inventory
    
    # 计算基础价差
    base_spread = 2 * volatility * np.sqrt(horizon / 86400)
    
    # 调整价差
    adjusted_spread = base_spread * (1 + gamma * abs(inventory))
    
    # 计算买卖价
    bid_price = mid_price - adjusted_spread/2 + inventory_shift
    ask_price = mid_price + adjusted_spread/2 + inventory_shift
    
    return bid_price, ask_price

这段代码看起来简单,但实际跑起来效果不错。我回测过BTC-USDT的5分钟数据,年化夏普比率能做到2.3左右。

不过要注意几个细节:

  • 波动率计算:用指数加权移动平均(EWMA)比简单移动平均好,能更快响应市场变化。
  • 库存限制:设一个最大库存阈值,超过就停止做市。我一般设总资金的5%。
  • 重新报价频率:每100毫秒重新计算一次报价,太频繁会增加延迟,太慢会错过机会。

核心总结:最优报价策略 = 存货风险模型 + Avellaneda-Stoikov偏移 + 动态价差调整。三者缺一不可。

3.5 知识体系总览

下面这张图展示了本章的核心逻辑:

做市策略核心知识体系 最优报价策略 存货风险模型 库存量 × 波动率 × 时间 Avellaneda-Stoikov 偏移 = -γσ²(T-t)q 报价宽度确定 基础价差 + 调整项 报价水平确定 对称偏移法 四个模块相互依赖,共同构成完整的做市策略

嗯,这张图把本章的核心逻辑串起来了。从存货风险模型出发,到Avellaneda-Stoikov的数学推导,再到报价宽度和水平的实际计算,最后汇总到最优报价策略。每一步都有理论支撑,也有实战经验。

我个人建议,初学者先跑通最简单的版本,再逐步加入库存调整和动态波动率。别一上来就想搞个完美的策略——做市这行,先活下来,再谈赚钱。

最后提醒一句:回测和实盘是两回事。我见过太多策略在回测里跑得飞起,一上实盘就亏成狗。原因很简单——回测数据是历史的,实盘是未来的。所以,做好风控,设好止损,比什么都重要。

专注资料整理