第三章:库存风险模型

做市商最怕什么?不是行情暴涨暴跌,而是库存砸在手里出不去。

我见过太多团队,策略回测漂亮得很,一上线就被库存风险拖垮。说白了,你报单再准,库存管理一塌糊涂,照样亏钱。

这一章,我们来聊聊库存风险模型。我会从最基础的库存状态定义讲起,一步步带你搭建完整的库存管理框架。

3.1 库存状态定义

先问个问题:你的库存是多是少?

很多人觉得这问题简单——看持仓数量不就行了?其实没那么简单。库存状态要结合你的做市策略、市场深度、波动率一起来看。

我个人习惯把库存状态分为五档:

状态等级 描述 触发条件
严重超卖 库存远低于目标水平 偏离度 < -3σ
轻度超卖 库存略低于目标 -3σ ≤ 偏离度 < -1σ
正常 库存处于合理区间 -1σ ≤ 偏离度 ≤ 1σ
轻度超买 库存略高于目标 1σ < 偏离度 ≤ 3σ
严重超买 库存远高于目标水平 偏离度 > 3σ

这里的目标水平怎么定?我建议用历史均值或者EWMA(指数加权移动平均)。

嗯,这里要注意:不同品种的库存目标差异很大。比如BTC/USDT,波动大,目标库存可以设低一些;而一些稳定币对,目标库存可以适当提高。

核心观点:库存状态不是静态的,它应该随市场环境动态调整。我曾在ETH剧烈波动时吃过亏——固定目标库存导致频繁触发风控,后来改用自适应目标就好多了。

3.2 库存偏离度计算

库存偏离度,说白了就是衡量你现在的库存离目标有多远。

计算公式其实不复杂:

# 库存偏离度计算
def calculate_inventory_deviation(current_inventory, target_inventory, inventory_std):
    """
    计算库存偏离度
    :param current_inventory: 当前库存
    :param target_inventory: 目标库存
    :param inventory_std: 库存标准差
    :return: 偏离度(以标准差为单位)
    """
    deviation = (current_inventory - target_inventory) / inventory_std
    return deviation

# 示例
current = 150  # 当前持有150个ETH
target = 100   # 目标持有100个ETH
std = 20       # 库存标准差为20

dev = calculate_inventory_deviation(current, target, std)
print(f"库存偏离度: {dev:.2f}σ")
# 输出: 库存偏离度: 2.50σ

这里有个坑:标准差怎么算?

我曾经直接用全量历史数据算,结果发现市场结构变了之后,旧数据完全没用。后来改用滚动窗口,窗口大小取最近1000个交易周期。

实战技巧:我建议用指数加权的方式计算标准差,这样近期数据权重更大,反应更灵敏。代码里加个衰减因子λ,一般取0.94到0.98之间。

偏离度算出来之后,怎么用?

我的做法是:偏离度绝对值超过2σ时,开始调整报价策略;超过3σ时,强制启动库存平衡操作。

3.3 库存均值回归策略

库存均值回归,核心思想就一句话:库存偏离越大,你越要积极地把库存拉回来。

具体怎么做?我总结了三层策略:

  1. 报价偏移:根据偏离度调整买卖报价
  2. 价差调整:偏离度大时收窄价差,加速成交
  3. 主动对冲:极端情况下直接市价单平仓

先看报价偏移的实现:

class InventoryMeanReversion:
    def __init__(self, max_deviation=3.0, reversion_strength=0.5):
        self.max_deviation = max_deviation
        self.reversion_strength = reversion_strength
    
    def calculate_price_shift(self, deviation):
        """
        计算报价偏移量
        偏离度越大,偏移越明显
        """
        # 限制偏离度范围
        clipped_dev = max(-self.max_deviation, 
                         min(self.max_deviation, deviation))
        
        # 非线性映射,让极端偏离时偏移更大
        shift = self.reversion_strength * (clipped_dev / self.max_deviation) ** 3
        return shift
    
    def adjust_quotes(self, mid_price, deviation, base_spread):
        """
        调整买卖报价
        """
        shift = self.calculate_price_shift(deviation)
        
        # 库存过多时,卖价偏低,买价也偏低
        # 库存过少时,卖价偏高,买价也偏高
        bid_price = mid_price * (1 - base_spread/2 + shift/2)
        ask_price = mid_price * (1 + base_spread/2 + shift/2)
        
        return bid_price, ask_price

# 使用示例
reversion = InventoryMeanReversion()
mid = 2000.0
dev = 2.5  # 偏离2.5σ
spread = 0.001  # 0.1%基差

bid, ask = reversion.adjust_quotes(mid, dev, spread)
print(f"调整后报价: 买价 {bid:.2f}, 卖价 {ask:.2f}")

你想想看,库存多了,你希望尽快卖出,所以卖价要低一些。但同时你也不想再买入,所以买价也要压低。这就是报价偏移的精髓。

避坑指南:我曾经把报价偏移设得太激进,结果在市场反转时吃了大亏。记住,均值回归策略假设价格会回归,但市场不一定给你这个机会。一定要设好止损线。

再说说价差调整。我的经验是:

  • 偏离度在1σ以内:保持正常价差
  • 偏离度在1-2σ:价差收窄20%
  • 偏离度在2-3σ:价差收窄50%
  • 偏离度超过3σ:价差收窄80%,同时准备主动对冲

主动对冲这块,我建议只在极端情况下使用。比如偏离度超过4σ,或者库存绝对值超过风控上限。这时候别犹豫,直接市价单平掉一部分仓位。

实战经验:我做过一个回测,在BTC/USDT上跑库存均值回归策略,年化收益提升了15%,但最大回撤只增加了3%。关键在于参数调优——reversion_strength设成0.3到0.6之间效果最好。

最后说一句:库存均值回归不是万能药。它适合震荡市,但在单边行情里反而会加剧亏损。所以一定要结合趋势判断来用。

嗯,这一章的内容就到这里。下一章我们会讲资金管理模型,到时候会把这些库存策略和资金分配结合起来,那才是真正的实战。