4. 库存管理模型:基于马尔可夫链的库存预测,最优库存水平计算

做市商最怕什么?怕库存被砸穿,也怕库存被拉爆。

说白了,库存管理就是高频做市里的“命门”。你策略再牛,订单流预测再准,库存一失控,前面赚的全得吐回去。我个人习惯把库存管理比作“走钢丝”——库存高了怕方向反转,库存低了又怕错失行情。

这一章,我们来聊聊怎么用马尔可夫链预测库存变化,以及如何算出那个“刚刚好”的最优库存水平。

4.1 为什么是马尔可夫链?

先问个问题:库存的变化有没有规律?

有,但很难用简单的线性模型去拟合。因为订单流是随机的,成交也是随机的。你想想看,下一秒的库存状态,其实只取决于当前的状态——你手里有多少货,以及接下来会成交多少。

这不就是马尔可夫链的典型场景吗?

马尔可夫链的核心假设是:未来只与现在有关,与过去无关。在高频做市里,这个假设基本成立。因为订单簿的微观结构变化极快,几毫秒前的库存状态对下一秒的影响微乎其微。

核心观点: 马尔可夫链把库存变化建模成一个状态转移过程。每个库存水平是一个“状态”,成交或撤单就是“转移事件”。

4.2 库存状态的离散化

实际交易中,库存是连续的——你可以持有100.5个ETH。但马尔可夫链要求状态是离散的。所以第一步,得把库存切分成若干档位。

我在项目中遇到过一个问题:档位切得太细,状态空间爆炸,计算量扛不住;切得太粗,精度又不够。后来我总结了一个经验:按最小交易单位的整数倍来切

举个例子,假设你交易的是BTC永续合约,最小交易单位是0.001 BTC。那你的库存状态可以设为:

  • 状态0:空仓(0 BTC)
  • 状态1:持有0.001 BTC
  • 状态2:持有0.002 BTC
  • ……
  • 状态N:持有N * 0.001 BTC

上限N怎么定?看你的风险敞口限制。比如你规定最大库存不能超过10 BTC,那N就是10000。嗯,这个状态空间确实不小,但别急,后面有办法优化。

4.3 转移概率矩阵的构建

有了状态,接下来就是算“从状态i跳到状态j的概率”。这个矩阵就是马尔可夫链的核心——转移概率矩阵P

怎么算?两种方式:

  1. 历史统计法: 回看过去一段时间,统计从库存i变成库存j的次数,除以总次数。
  2. 订单流模型法: 根据当前订单簿的买卖挂单量,估算成交概率,再推导转移概率。

我个人更推荐第二种。因为高频环境变化太快,历史统计往往滞后。用实时订单流来算,更贴近当前市场。

来看一段伪代码,展示怎么构建转移矩阵:

# 假设库存状态从0到N
N = 100  # 最大库存水平
P = [[0.0 for _ in range(N+1)] for _ in range(N+1)]

# 遍历每个状态
for i in range(N+1):
    # 计算从状态i转移到其他状态的概率
    # buy_prob: 下一笔成交是买入的概率(库存增加)
    # sell_prob: 下一笔成交是卖出的概率(库存减少)
    # idle_prob: 没有成交的概率(库存不变)
    
    # 从订单簿数据中实时计算
    buy_prob = orderbook.bid_volume / (orderbook.bid_volume + orderbook.ask_volume)
    sell_prob = orderbook.ask_volume / (orderbook.bid_volume + orderbook.ask_volume)
    idle_prob = 1.0 - (buy_prob + sell_prob)  # 简化处理
    
    # 填充转移概率
    if i > 0:
        P[i][i-1] = sell_prob  # 库存减少
    P[i][i] = idle_prob        # 库存不变
    if i < N:
        P[i][i+1] = buy_prob   # 库存增加

小技巧: 实际生产中,转移概率不是静态的。我习惯每100毫秒重新计算一次P矩阵,用滑动窗口的方式。这样既能跟上市场变化,又不会太耗CPU。

4.4 稳态分布与库存预测

有了转移矩阵,我们就可以做两件事:

  • 短期预测: 给定当前库存状态,预测未来几步的库存分布。
  • 长期预测: 计算稳态分布,看看如果一直做市,库存最终会收敛到什么水平。

短期预测很简单,就是矩阵乘法。假设当前库存状态向量是v₀(一个one-hot向量),那么t步后的状态分布就是:

vₜ = v₀ × Pᵗ

稳态分布呢?就是解方程 π = π × P,其中π是稳态概率向量。这个方程的解,告诉你长期来看,库存落在每个档位的概率是多少。

我曾经踩过一个坑:直接用线性代数库去解稳态分布,结果矩阵太大,算到超时。后来改用幂迭代法,每次只做矩阵向量乘法,收敛很快。嗯,这里要注意,幂迭代法需要保证矩阵是遍历的——也就是说,从任何状态都能到达任何其他状态。

4.5 最优库存水平的计算

预测库存只是第一步。我们真正想要的是:当前库存应该控制在什么水平,才能让预期收益最大、风险最小?

这就涉及到最优库存水平的计算了。我常用的方法是“风险调整后的期望收益最大化”。

定义几个变量:

  • Q:当前库存量
  • V(Q):持有库存Q的“价值函数”,包括预期收益和风险惩罚
  • γ:风险厌恶系数,越大越厌恶风险
  • σ²:库存价值的波动率

那么最优库存水平Q*满足:

Q* = argmax [ E[ΔP×Q] - γ × σ² × Q² ]

其中E[ΔP×Q]是预期库存收益,γ×σ²×Q²是风险惩罚项。

这个公式看着简单,但实际用起来有几个坑:

避坑指南: 我曾经直接把波动率σ设成历史波动率,结果在市场突变时,最优库存水平完全失效。后来我改成用实时波动率,结合马尔可夫链预测的库存分布来动态调整γ参数。效果好了很多。

来看一个实际的计算流程:

def optimal_inventory(current_inv, P, gamma, sigma):
    """
    计算最优库存水平
    current_inv: 当前库存
    P: 转移概率矩阵
    gamma: 风险厌恶系数
    sigma: 波动率
    """
    # 1. 用马尔可夫链预测未来N步的库存分布
    N = 10  # 预测步数
    v = [0] * len(P)
    v[current_inv] = 1.0
    future_dist = v
    for _ in range(N):
        future_dist = mat_vec_mul(future_dist, P)
    
    # 2. 计算每个库存水平的期望收益
    expected_profit = 0
    for inv_level, prob in enumerate(future_dist):
        # 假设每单位库存的预期收益是spread的一半
        expected_profit += prob * inv_level * (spread / 2)
    
    # 3. 计算风险惩罚
    risk_penalty = gamma * (sigma ** 2) * (current_inv ** 2)
    
    # 4. 最优库存就是让 expected_profit - risk_penalty 最大的那个
    # 这里简化处理,实际需要遍历或求导
    optimal = current_inv
    best_value = expected_profit - risk_penalty
    
    # 尝试微调库存水平
    for delta in [-1, 0, 1]:
        new_inv = current_inv + delta
        if 0 <= new_inv <= N:
            new_value = expected_profit - gamma * (sigma ** 2) * (new_inv ** 2)
            if new_value > best_value:
                best_value = new_value
                optimal = new_inv
    
    return optimal

4.6 知识体系总览

这一章的内容比较多,我画了一张图帮你理清思路:

库存管理模型知识体系 订单簿数据 历史成交数据 风险参数(γ,σ) 马尔可夫链库存模型 状态离散化 → 转移概率矩阵 → 稳态分布 库存预测 短期分布 + 长期稳态 最优库存水平 期望收益 - 风险惩罚 动态报价调整 · 库存对冲 · 风险预警

4.7 实战中的几个要点

最后,分享几个我在实战中总结的要点:

  • 状态空间压缩: 如果N太大,可以用“分桶”的方式,把相近的库存水平合并成一个状态。比如0-0.1 BTC算一个状态,0.1-0.2 BTC算另一个。精度损失不大,但计算量能降一个数量级。
  • 转移矩阵的更新频率: 我建议不要每笔成交都更新,那样太频繁。每100-200毫秒更新一次就够,跟订单簿的快照频率保持一致。
  • 最优库存不是固定值: 它是动态的,随市场波动率和你的风险偏好变化。我习惯在系统里设一个“目标库存区间”,只要库存落在这个区间内,就不做强制调整,避免频繁交易产生额外成本。

一句话总结: 马尔可夫链帮你“看清”库存的未来走势,最优库存水平帮你“决定”现在该怎么做。两者结合,就是一套完整的库存管理闭环。

好了,这一章就到这里。库存管理是个细活,代码写起来不难,难的是参数调优和边界情况处理。多跑回测,多观察实盘,慢慢就能找到感觉。


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