3. 做市策略设计原理:库存管理、报价宽度、报价更新频率、最优报价策略

做市策略的核心,说白了就是回答三个问题:报什么价?报多少量?什么时候更新?

这三个问题背后,藏着四个关键设计维度——库存管理、报价宽度、报价更新频率、最优报价策略。我做了几年量化做市,踩过不少坑,今天就把这些经验掰开揉碎讲给你听。

3.1 库存管理:做市商的命门

库存管理,是做市策略的基石。你想想看,做市商本质上就是个「中间商」,赚的是买卖价差。但中间商最怕什么?怕货砸手里。

我刚开始做市时,有一次在ETH上挂了大量买单,结果行情突然跳水,库存瞬间变成负值——也就是我手里全是高价买的货,卖不出去。那次教训让我明白:库存管理不是「要不要持仓」,而是「持多少、持多久」

3.1.1 库存目标与偏离惩罚

每个做市策略都应该有一个「目标库存水平」。通常设为0,也就是中性库存。但实际中,你可以根据市场观点调整这个目标。

偏离目标库存时,策略需要惩罚报价。怎么惩罚?我习惯用这个公式:

# 库存偏离惩罚系数
inventory_penalty = -gamma * (current_inventory - target_inventory)

# 调整后的报价
adjusted_bid = mid_price + spread/2 + inventory_penalty
adjusted_ask = mid_price - spread/2 + inventory_penalty

这里的 gamma 是库存厌恶系数。值越大,库存偏离时报价调整越激进。

关键点:库存惩罚不是对称的。手里货多时,要压低卖价、抬高买价,鼓励卖出、抑制买入。反之亦然。

3.1.2 库存再平衡策略

当库存偏离到一定程度,光靠报价调整可能不够。这时候需要主动再平衡。

我常用的三种方式:

  • 激进报价:在偏离方向加大报价偏移,加速库存回归
  • 对冲交易:在相关品种上做反向操作(比如BTC和ETH联动)
  • 暂停做市:极端情况下,直接撤单,等市场恢复再说

我的经验:别等到库存爆了才动手。设置一个「警戒线」,比如偏离超过目标库存的20%就开始激进调整。我曾经吃过亏,等到偏离50%才动手,结果滑点大得吓人。

3.2 报价宽度:赚多少 vs 成交概率

报价宽度,就是买卖价差。这个参数直接决定了你的盈利能力和成交概率。

价差太宽,赚得多但成交少;价差太窄,成交多但赚得少。这是个典型的权衡问题。

3.2.1 动态价差模型

固定价差是新手做法。真正有效的策略,应该根据市场状态动态调整价差。

我常用的模型:

# 动态价差计算
base_spread = 2 * (tick_size + alpha * volatility)

# 波动率调整
volatility = std(returns, window=20) * sqrt(365)

# 最终价差
dynamic_spread = base_spread * (1 + beta * order_imbalance)

其中:

  • tick_size:最小价格变动单位
  • alpha:波动率敏感系数(我一般设0.5-1.5)
  • beta:订单簿不平衡调整系数

注意:波动率越高,价差应该越宽。但别调得太激进,否则你会被高频交易者「剥头皮」。我见过有人把alpha设到3,结果价差宽到根本没人成交。

3.2.2 价差与库存的联动

价差不是独立参数,它和库存管理是联动的。库存偏离大时,不仅要调整报价位置,还要调整价差宽度。

库存状态 价差调整 原因
中性库存 正常价差 正常赚取买卖价差
多头偏离 收窄卖价、放宽买价 鼓励卖出、抑制买入
空头偏离 收窄买价、放宽卖价 鼓励买入、抑制卖出
极端偏离 单边报价 只挂库存回归方向的单

3.3 报价更新频率:快 vs 稳

报价更新频率,决定了你的策略对市场变化的响应速度。

频率太高,容易产生大量撤单费(交易所收的);频率太低,报价可能过时,被市场「吃掉」。

3.3.1 事件驱动 vs 时间驱动

我习惯用事件驱动的方式更新报价:

  • 成交事件:我的单子被吃了,立即更新
  • 订单簿变化:最佳买卖价变化超过阈值,更新
  • 市场波动:波动率突变,更新
  • 定时更新:兜底策略,比如每500ms强制更新一次
# 伪代码:事件驱动的报价更新
def on_market_event(event):
    if event.type == 'TRADE' and event.price in [my_bid, my_ask]:
        update_quotes()  # 我的单被吃了,立即更新
    elif event.type == 'ORDERBOOK_CHANGE':
        if abs(event.new_best_bid - last_best_bid) > threshold:
            update_quotes()  # 市场变了,更新
    elif event.type == 'TIMER':
        if time_since_last_update > 500:  # ms
            update_quotes()  # 兜底更新

避坑指南:我曾经把更新频率设到10ms一次,结果一天下来撤单费比盈利还高。后来改成事件驱动+500ms兜底,效果好了很多。记住:不是越快越好,是「该快的时候快,该稳的时候稳」

3.4 最优报价策略:把上面三个串起来

库存管理、报价宽度、更新频率,这三个东西不是孤立的。最优报价策略,就是把它们整合成一个有机整体。

3.4.1 核心框架

我用的框架是这样的:

class OptimalMarketMaker:
    def __init__(self, gamma, alpha, beta, target_inventory=0):
        self.gamma = gamma  # 库存厌恶系数
        self.alpha = alpha  # 波动率敏感系数
        self.beta = beta    # 订单簿不平衡系数
        self.target = target_inventory
    
    def calculate_quotes(self, market_state):
        # 1. 计算基础价差
        vol = self._estimate_volatility(market_state)
        base_spread = 2 * (market_state.tick_size + self.alpha * vol)
        
        # 2. 库存调整
        inventory_deviation = market_state.my_inventory - self.target
        inventory_penalty = -self.gamma * inventory_deviation
        
        # 3. 订单簿不平衡调整
        imbalance = market_state.bid_volume - market_state.ask_volume
        spread_adjustment = self.beta * imbalance
        
        # 4. 最终报价
        spread = base_spread * (1 + spread_adjustment)
        mid = market_state.mid_price + inventory_penalty
        
        bid = mid - spread / 2
        ask = mid + spread / 2
        
        return bid, ask

3.4.2 参数优化

这些参数(gamma、alpha、beta)怎么设?我建议用历史数据做回测优化。

优化目标通常是:夏普比率收益/风险比。别只看总收益,风险控制才是做市商的长久之道。

我的经验:参数优化时,记得做「稳健性检验」。也就是在多个市场周期上测试同一组参数。我见过有人在一个月的数据上优化出完美参数,换到另一个月就亏成狗。说白了,就是过拟合了。

3.5 知识体系总览

下面这张图,把做市策略设计的核心逻辑串起来了:

做市策略设计核心逻辑 最优报价策略 库存管理 报价宽度 报价更新频率 目标库存 偏离惩罚 再平衡策略 动态价差 波动率调整 库存联动 事件驱动 时间驱动 撤单费权衡 三者联动 → 最优报价策略 库存管理决定方向,报价宽度决定利润,更新频率决定响应速度

嗯,到这里,做市策略设计的四个核心维度就讲完了。库存管理是「方向盘」,报价宽度是「油门」,更新频率是「变速箱」,最优报价策略就是那个「老司机」——把三者协调好,才能稳稳地赚钱。

最后一句:别想着一次就把参数调完美。做市是个动态博弈的过程,市场在变,你的策略也得跟着变。多回测、多复盘,慢慢就能找到感觉。


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