做市策略核心指标:买卖价差、市场深度、库存风险、skew与delta

做市策略说白了就是「低买高卖」的自动化版本。但真要把这件事做好,你得盯住几个核心指标。我做了这么多年低延迟做市系统,发现很多新手一上来就写策略逻辑,结果跑起来才发现——连最基本的价差都没算对。

今天咱们就把这几个指标掰开揉碎讲清楚。嗯,每个指标我都踩过坑,有些坑现在想起来还肉疼。

买卖价差(Bid-Ask Spread)

买卖价差,就是市场上最优买价和最优卖价之间的差值。公式很简单:

Spread = Ask_Price - Bid_Price

但实际做市时,我们更关心的是有效价差。什么意思?

举个例子。假设某股票最优买价是10.00,最优卖价是10.02,名义价差是2分钱。但如果你挂单10.00买入,成交概率可能只有30%。真正能成交的价差,往往比名义价差大。

我个人习惯:用加权平均价差来评估流动性。把每个价位的挂单量考虑进去,算出来的才是「真实价差」。

我在项目中遇到过一种情况:某个币种在交易所显示价差只有0.01%,但实际一成交,滑点直接吃掉0.05%。为什么?因为价差虽然窄,但深度极浅,大单根本吃不到。

所以,价差要结合深度一起看。后面会讲。

市场深度(Market Depth)

市场深度描述的是「在某个价格水平上,有多少订单等着成交」。说白了,就是订单簿上每一档的挂单量。

深度越厚,大单对价格的冲击越小。深度越薄,一个100手的单子就能把价格打穿好几档。

我常用的深度指标有两个:

  • 总深度:从最优价到第N档的总挂单量
  • 深度斜率:价格每变动一个tick,挂单量的变化率

举个例子,假设订单簿长这样:

档位 买价 买量 卖价 卖量
1 10.00 1000 10.02 800
2 9.99 2000 10.03 1500
3 9.98 3000 10.04 2500

前3档的总买深度是6000,总卖深度是4800。买盘明显比卖盘厚。这时候如果你做市,挂买单的风险比挂卖单小——因为万一价格下跌,下面有更厚的买盘撑着。

避坑指南:我曾经在深度薄的品种上同时挂了双边订单,结果一个突发消息导致价格瞬间跳空,两边都被吃掉,库存直接爆仓。后来我加了个深度阈值——深度低于某个值,只做单边。

库存风险(Inventory Risk)

做市商最怕什么?不是价格涨跌,而是库存不对称

你想想看,做市策略本质上是赚价差,不是赌方向。但如果你的库存里全是多头,价格一跌,账面亏损就来了。这就是库存风险。

衡量库存风险,我一般用两个维度:

  • 库存价值:当前持仓的总市值
  • 库存敞口:净持仓相对于目标库存的偏离度

举个例子。假设你的目标库存是0(中性),但实际持有了1000股多头。这时候库存敞口就是1000股。如果股价跌1%,你就亏1000股×1%的市值。

怎么控制?我常用的方法是动态调整报价

# 伪代码示例
if inventory > target:
    # 库存偏多,降低买价,提高卖价
    bid_price = fair_price - spread/2 - skew
    ask_price = fair_price + spread/2 + skew
else:
    # 库存偏空,提高买价,降低卖价
    bid_price = fair_price - spread/2 + skew
    ask_price = fair_price + spread/2 - skew

说白了,库存多了就压价卖,库存少了就提价买。这个skew就是调节力度。

注意:skew不能设太大,否则你的报价会偏离市场太远,根本成交不了。我见过有人把skew设成价差的2倍,结果挂了一整天一单没成。

Skew与Delta

Skew和Delta是做市策略里最容易被混淆的两个概念。我简单说清楚。

Skew:报价偏移量。用来调节买卖报价,以控制库存风险。skew越大,报价越偏向于「去库存」的方向。

Delta:价格敏感度。更准确地说,是持仓价值对价格变动的敏感度。对于现货,delta就是持仓数量。对于期权,delta是期权价格对标的物价格的偏导数。

两者有什么关系?

Skew是主动调节的手段,Delta是被动暴露的结果。你通过调整skew来影响delta,最终目标是让delta趋近于0(中性)。

举个例子:

  • 当前delta = +500(多头500股)
  • 你希望delta = 0
  • 于是你设置skew = 0.01,让卖价降低0.01,吸引卖出成交
  • 成交后,delta下降,skew也随之减小

这是一个闭环反馈系统。我习惯用PID控制器来调节skew:

class SkewController:
    def __init__(self, kp, ki, kd):
        self.kp = kp  # 比例系数
        self.ki = ki  # 积分系数
        self.kd = kd  # 微分系数
        self.prev_error = 0
        self.integral = 0
    
    def update(self, current_delta, target_delta):
        error = current_delta - target_delta
        self.integral += error
        derivative = error - self.prev_error
        self.prev_error = error
        
        skew = (self.kp * error + 
                self.ki * self.integral + 
                self.kd * derivative)
        return skew

这个控制器会根据delta偏离程度,自动计算合适的skew。比例项处理当前偏差,积分项消除稳态误差,微分项抑制震荡。

我个人经验:kp、ki、kd这三个参数,千万别一上来就调。先固定kp,等策略稳定了再加ki。kd我一般设得很小,甚至为0——因为高频做市里,微分项容易放大噪声。

指标之间的联动关系

这几个指标不是孤立的。它们互相影响,形成一个动态系统。

举个例子:

  1. 市场深度突然变薄(比如大单撤单)
  2. 价差扩大,成交难度增加
  3. 库存无法快速调整,delta偏离增大
  4. skew被迫调大,报价偏离市场
  5. 进一步降低成交概率,库存风险累积

你看,一个深度变化,能引发连锁反应。所以做市系统必须实时监控所有指标,任何一个指标超出阈值,都要触发保护机制。

我常用的保护逻辑:

  • 价差 > 阈值 → 暂停做市
  • 深度 < 阈值 → 只做单边
  • delta > 阈值 → 强制平仓
  • skew > 阈值 → 报警人工干预

嗯,说到报警,我记得有一次凌晨3点,系统报警说skew超过了0.05。我爬起来一看,原来是交易所的撮合引擎出了bug,订单簿数据全乱了。要不是这个指标报警,那天晚上库存得亏掉几十万。

所以,指标不只是用来赚钱的,更是用来保命的。

最后说一句:这些指标的计算,一定要在低延迟路径上完成。我见过有人把指标计算放在Python层,结果每次计算要花几微秒——对于高频做市来说,这几微秒足够让订单飞走了。建议用C++实现核心指标计算,Python只做监控和日志。