第16章 统计套利进阶:卡尔曼滤波动态基差估计、状态空间模型应用、时变参数模型
各位,欢迎来到统计套利的进阶篇。
前面我们聊的基差交易,大多假设价差是稳定的。但真实市场哪有那么乖?价差会漂移,参数会变化,连回归关系都可能说翻脸就翻脸。这时候,静态的OLS(普通最小二乘法)就不够用了。
我们需要一套能“自我进化”的模型。今天要讲的卡尔曼滤波、状态空间模型和时变参数模型,就是干这个的。
16.1 为什么需要动态估计?
先问一个问题:你用一个固定回归系数去做配对交易,结果发现最近半年这个系数一直在变。怎么办?
我早年做螺纹钢和热卷的套利时,就踩过这个坑。当时用过去两年的数据算出一个对冲比例,觉得稳了。结果市场结构一变,那个比例直接失效,亏得我头皮发麻。
后来我明白了:市场参数不是常数,是随机游走的。
静态模型的问题在于:
- 它把所有历史数据一视同仁,旧数据和新数据权重一样
- 它假设关系不变,但市场结构会变
- 它无法处理缺失值和异频数据
说白了,静态模型就像用后视镜开车。而动态模型,是给你装了个实时雷达。
16.2 状态空间模型:把问题拆成两层
状态空间模型的核心思想很简单:把系统拆成“状态”和“观测”两层。
- 状态方程:描述隐藏变量(比如真实基差、对冲比例)如何随时间演变
- 观测方程:描述我们能看到的价格数据如何由状态变量生成
举个例子。假设我们做焦煤和焦炭的套利。真实的对冲比例β_t是随时间变化的,它服从一个随机游走:
β_t = β_{t-1} + w_t, w_t ~ N(0, Q)
而我们观测到的价差y_t,由这个β_t决定:
y_t = β_t * x_t + v_t, v_t ~ N(0, R)
这里w_t是状态噪声,v_t是观测噪声。Q和R是我们要估计的超参数。
我个人习惯把Q设得大一点,让模型对变化更敏感。但也不能太大,否则模型会跟着噪声乱跳。这个度,得靠回测去调。
16.3 卡尔曼滤波:递归的“预测-更新”循环
卡尔曼滤波是状态空间模型的标准求解器。它像一个聪明的滤波器,每来一个新数据,就做两件事:
- 预测:根据上一时刻的状态,预测当前时刻的状态
- 更新:用当前观测值修正预测,得到更准确的状态估计
这个递归过程,计算量极小,非常适合高频场景。
核心公式(简化版):
# 预测步骤
β_pred = β_prev
P_pred = P_prev + Q
# 更新步骤
K = P_pred * x / (x * P_pred * x + R) # 卡尔曼增益
β_updated = β_pred + K * (y - β_pred * x)
P_updated = (1 - K * x) * P_pred
你看,卡尔曼增益K决定了我们更相信预测还是更相信观测。如果观测噪声R很大,K就小,模型更依赖预测。如果状态噪声Q很大,K就大,模型更依赖新数据。
我曾经在沥青和原油的套利中用过这个。当时原油波动剧烈,静态模型完全跟不上。换成卡尔曼滤波后,对冲比例每天自动调整,回测夏普直接从0.8跳到1.5。嗯,效果立竿见影。
16.4 时变参数模型:让系数自己“走路”
时变参数模型(TVP)是状态空间模型的一个特例。它假设所有回归系数都随时间变化,且变化方式通常是随机游走。
为什么用随机游走?因为金融数据里,参数的变化往往没有明显的均值回归特性。你今天看到的关系,明天可能就变了,而且你不知道它会往哪个方向变。
实现时,我建议用Python的pykalman或statsmodels的UnobservedComponents。下面是一个实战代码片段:
from pykalman import KalmanFilter
import numpy as np
# 构建卡尔曼滤波器
kf = KalmanFilter(
transition_matrices=[1], # 状态转移矩阵
observation_matrices=[x], # 观测矩阵
initial_state_mean=0,
initial_state_covariance=1,
transition_covariance=Q, # 状态噪声
observation_covariance=R # 观测噪声
)
# 滤波
state_means, state_covs = kf.filter(y)
这里有个坑:初始参数Q和R怎么设?
我的经验是:先用EM算法(期望最大化)从一段历史数据中估计出Q和R的初始值。然后根据实际交易效果微调。如果模型反应太慢,就增大Q;如果太敏感,就减小Q。
避坑指南:
我曾经在铁矿石和螺纹钢的套利中,把Q设得太小,导致模型对2021年那波政策冲击完全没反应。后来我改成用滚动窗口的MLE(最大似然估计)每季度重新估计一次Q和R,才解决了这个问题。
16.5 实战中的注意事项
说了这么多,最后给几个实战建议:
| 问题 | 解决方案 |
|---|---|
| 参数Q/R难以确定 | 用EM算法或贝叶斯方法估计,或做网格搜索 |
| 模型发散(状态估计爆炸) | 检查观测方程是否可识别,或加入正则化 |
| 计算速度要求高 | 用Cython或Numba加速,或降低状态维度 |
| 多品种配对 | 用多维状态空间模型,但注意维度灾难 |
另外,我建议你在实盘前,先用历史数据做一遍“回溯滤波”。也就是用过去的数据跑一遍卡尔曼滤波,看看估计出的时变参数是否合理。如果参数波动太大,说明模型可能过拟合了。
重要提醒:
卡尔曼滤波不是万能的。如果市场结构发生突变(比如交易所修改合约规则),任何动态模型都需要重新校准。别指望模型能自动适应一切。
16.6 一张图总结本章逻辑
下面这张图展示了从静态模型到动态模型的演进路径,以及卡尔曼滤波在其中的位置:
从这张图可以看得很清楚:静态模型是起点,状态空间模型是框架,卡尔曼滤波是求解工具,时变参数模型是具体应用。它们层层递进,最终服务于实战中的动态基差估计。
好了,这一章的内容就到这里。动态模型是个好东西,但别迷信它。记住:模型是工具,不是上帝。用得好,它能帮你赚钱;用得不好,它也能让你亏得莫名其妙。多测试,多思考,才是正道。
公众号:蓝海资料掘金营,微信deep3321