4、库存动态平衡的数学建模
做市策略的核心,说白了就是跟库存风险打交道。你赚的那点价差,可能一次库存失控就全赔进去了。所以这一章,我们来聊聊怎么用数学工具把库存风险管起来。
我个人习惯把库存模型分成五块:随机过程模型、均值回归模型、VaR模型、ES模型,最后是优化目标函数。咱们一个一个来。
4.1 库存随机过程模型
做市商的库存变化,本质上是个随机过程。你想想看,每笔订单的到达时间、买卖方向、数量,都是随机的。我刚开始做的时候,总想预测下一秒的库存,后来发现——别费那个劲了,用随机过程建模更靠谱。
最常见的假设是:库存变化服从布朗运动。公式长这样:
dI(t) = μ dt + σ dW(t)
其中 I(t) 是 t 时刻的库存,μ 是漂移项(你主动调整库存的趋势),σ 是波动率,dW(t) 是标准布朗运动增量。
嗯,这里要注意:实际交易中,μ 往往不为零。因为做市商不是被动接单,你会主动报价来引导库存回归。所以 μ 其实是你的策略参数。
4.2 均值回归模型
做市商的库存,天然有均值回归的特性。为什么?因为你的报价策略会迫使库存往目标水平靠。比如库存多了,你就压低买价、抬高卖价,自然就卖出去了。
我常用的模型是 Ornstein-Uhlenbeck 过程:
dI(t) = θ (μ_target - I(t)) dt + σ dW(t)
这里 θ 是回归速度,μ_target 是目标库存水平(通常是0,或者某个安全区间中值)。θ 越大,库存回归越快,但交易成本也越高。
我曾经踩过一个坑:把 θ 设得太大,结果频繁调价,手续费吃掉了一大半利润。后来学乖了,θ 值用历史数据拟合,别拍脑袋定。
- θ:回归速度,建议 0.1~0.5 之间
- μ_target:目标库存,一般设为 0
- σ:波动率,根据品种调整
4.3 库存风险价值(VaR)模型
VaR 是个老生常谈的东西了。但在做市场景下,它的用法有点不一样。我们关心的是:在未来 Δt 时间内,库存可能的最大亏损是多少?
公式很简单:
VaR(α) = - (μ * Δt + σ * √Δt * z_α) * |I|
其中 z_α 是标准正态分布的 α 分位数,|I| 是当前库存的绝对值。α 通常取 95% 或 99%。
举个例子:假设你持有 1000 个 ETH,日波动率 2%,95% VaR 就是:
VaR(95%) = - (0 + 0.02 * √1 * 1.645) * 1000 = -32.9 ETH
也就是说,有95%的把握,一天内亏损不超过 32.9 个 ETH。
4.4 库存预期短缺(ES)模型
ES 模型,也叫条件 VaR。它回答的是:如果亏损超过了 VaR 阈值,平均会亏多少?
公式:
ES(α) = - (μ * Δt + σ * √Δt * φ(z_α) / (1-α)) * |I|
其中 φ 是标准正态分布的密度函数。对于正态分布,ES 大约是 VaR 的 1.2~1.5 倍。
我个人习惯同时看 VaR 和 ES。如果 ES 远大于 VaR,说明尾部风险很大,这时候我会主动减仓。记得有一次做比特币做市,VaR 显示风险可控,但 ES 高得吓人。我没在意,结果第二天暴跌,直接亏了三个月的利润。从那以后,我再也不敢只看 VaR 了。
| 指标 | 含义 | 适用场景 |
|---|---|---|
| VaR | 最大可能亏损(给定置信水平) | 日常风控阈值 |
| ES | 尾部平均亏损 | 极端行情预警 |
4.5 库存优化目标函数
好了,前面都是铺垫。现在我们来解决核心问题:怎么在控制风险的同时,最大化做市收益?
目标函数长这样:
max E[∫(spread * trade_rate - cost) dt] - λ * risk_penalty
其中:
- spread:买卖价差
- trade_rate:成交速率
- cost:交易成本(手续费、滑点等)
- λ:风险厌恶系数
- risk_penalty:风险惩罚项(可以用 VaR 或 ES)
这个优化问题,说白了就是在「多赚钱」和「少担风险」之间找平衡。λ 越大,策略越保守。
我一般用动态规划来解。把库存离散化成网格,每个网格点计算最优报价。代码大概长这样:
def optimize_inventory(I, params):
# I: 当前库存
# params: 市场参数、风险偏好等
V = np.zeros((max_I+1, T+1)) # 价值函数
for t in range(T-1, -1, -1):
for i in range(max_I+1):
# 计算每个库存水平下的最优报价
best_value = -np.inf
for bid, ask in possible_quotes:
next_inv = i + trade_flow(bid, ask)
reward = spread_profit(bid, ask) - risk_cost(i)
value = reward + discount * V[next_inv, t+1]
if value > best_value:
best_value = value
V[i, t] = value
return V[I, 0]
最后说一句:这些模型都是工具,不是真理。市场变了,参数就得调。我每周都会重新拟合一次模型参数,别偷懒。