跳到正文

卡尔曼滤波应用:Alpha 信号、Beta、动态因子

时变 beta、噪声信号提纯、配对交易对冲比率、动态因子——这些应用其实是同一个状态空间模型换皮,真正的自由度只有一个信噪比。讲清楚这个母模型,以及实现时会踩的坑。

第 2 篇 · 共 12 篇 约 13 分钟

卡尔曼滤波在教科书里是个估计算法,在交易系统里是台在线学习机器:给定一串观测,它在每个时点只用到目前为止的数据产生隐状态的最优线性估计,不需要批量重拟合。这个性质对交易信号、风险管理这类”信念必须随新数据更新”的场景正中要害。

但这篇文章想说的不止是”卡尔曼滤波有很多应用”。真正值得看清的一点是:时变 beta、alpha 信号提纯、动态对冲比率、在线回归——这些听起来各不相同的应用,骨子里是同一个模型换皮:状态走随机游走,观测是状态加噪声。整个模型真正的自由度只有一个信噪比 ση2/σε2\sigma_\eta^2 / \sigma_\varepsilon^2,它决定滤波器多信新数据、多信旧信念。把这个母模型吃透,剩下的应用就是给它加维度、加回归子、或者放松线性。框架出处是 Hamilton (1994, 第 13 章)、Tsay (2010, 第 11 章)、Harvey (1989) 和 Durbin & Koopman (2012)。

递归形式:为什么它能在线跑

卡尔曼滤波本质上是递归最小二乘。每个时点做四件事:用状态方程预测下一状态;观察新数据点;算创新(预测误差);用创新更新状态估计。这个递推在数学上等价于高斯先验下的贝叶斯更新——每次观测提供一小块信息修正先验,后验变成下一个先验。

递归形式的实际好处直接决定了它在生产系统里的地位。在线运行:不需要存储任何历史数据,只要当前状态估计 at\mathbf{a}_t 和协方差 Pt\mathbf{P}_t。计算便宜:每时点 O(m2)O(m^2)(mm 是状态维度),而在全部数据上重拟合回归是 O(Tm2)O(T m^2)。数值上也更稳:协方差递推让估计保持良好条件,批量最小二乘在条件差的数据上会被舍入误差折磨。

母模型:随机游走加噪声

先把最小的版本摆出来,后面所有应用都从它长出来:

αt+1=αt+ηt,ηt∼N(0,ση2)\alpha_{t+1} = \alpha_t + \eta_t, \quad \eta_t \sim N(0, \sigma_\eta^2) yt=αt+εt,εt∼N(0,σε2)y_t = \alpha_t + \varepsilon_t, \quad \varepsilon_t \sim N(0, \sigma_\varepsilon^2)

结构时间序列里管它叫局部水平模型。两个参数:状态噪声 ση2\sigma_\eta^2 说隐状态自己走多快,观测噪声 σε2\sigma_\varepsilon^2 说你每次看到的东西有多脏。信噪比 ση2/σε2\sigma_\eta^2 / \sigma_\varepsilon^2 决定滤波估计的平滑度,用 MLE 估计。别小看这个两参数模型——选状态空间结构时它是最安全的默认起点,先让它跑起来,再谈更花哨的动态。

它最直接的交易应用是从噪声预测子里提取 alpha 信号。假设有个噪声信号 sts_t 对应某个不可观测的”真实”alpha αt\alpha_t——比如一个慢动基本面模型的输出,日度更新是真实 alpha 的噪声估计。套进母模型:

αt+1=αt+ηt,ηt∼N(0,ση2)\alpha_{t+1} = \alpha_t + \eta_t, \quad \eta_t \sim N(0, \sigma_\eta^2) st=αt+εt,εt∼N(0,σε2)s_t = \alpha_t + \varepsilon_t, \quad \varepsilon_t \sim N(0, \sigma_\varepsilon^2)

滤波输出 α^t\hat{\alpha}_t,是给定到当前为止全部信号后对真实 alpha 的最佳估计,可以直接拿去做头寸规模或算风险调整收益。调参就是调那个信噪比:ση2\sigma_\eta^2 小,你在说 alpha 是慢动的,滤波器重度平滑、对状态变化反应迟钝;ση2\sigma_\eta^2 大,滤波器紧咬 sts_t。两个方差都用极大似然估计——MLE 在参数空间内部一致且渐近正态,唯一要留意的是边界:如果真实 ση2=0\sigma_\eta^2 = 0,MLE 的分布是非标准的。

加一个回归子:时变 Beta

CAPM beta 是回归 rtstock=α+βrtmarket+εtr_t^{stock} = \alpha + \beta r_t^{market} + \varepsilon_t 的斜率。标准估计给整个样本一个 β\beta,但 beta 不是常数——它随杠杆、商业周期、行业轮动漂移。把母模型的观测方程乘上一个回归子,就得到时变 beta 模型。假设 βt\beta_t 走随机游走:

βt+1=βt+ηt,ηt∼N(0,ση2)\beta_{t+1} = \beta_t + \eta_t, \quad \eta_t \sim N(0, \sigma_\eta^2)

观测超额收益 yt=rtstock−rtfy_t = r_t^{stock} - r_t^f 和 xt=rtmarket−rtfx_t = r_t^{market} - r_t^f,状态空间形式:

yt=βtxt+εt,εt∼N(0,σε2)y_t = \beta_t x_t + \varepsilon_t, \quad \varepsilon_t \sim N(0, \sigma_\varepsilon^2) βt+1=βt+ηt\beta_{t+1} = \beta_t + \eta_t

状态是标量 βt\beta_t,观测方程有 Zt=xtZ_t = x_t、Ht=σε2\mathbf{H}_t = \sigma_\varepsilon^2,状态方程有 T=1T = 1、R=1R = 1、Q=ση2Q = \sigma_\eta^2。递推写全也就七行:

β^t∣t−1=β^t−1\hat{\beta}_{t|t-1} = \hat{\beta}_{t-1} Pt∣t−1=Pt−1+ση2P_{t|t-1} = P_{t-1} + \sigma_\eta^2 vt=yt−xtβ^t∣t−1v_t = y_t - x_t \hat{\beta}_{t|t-1} Ft=xt2Pt∣t−1+σε2F_t = x_t^2 P_{t|t-1} + \sigma_\varepsilon^2 Kt=xtPt∣t−1/FtK_t = x_t P_{t|t-1} / F_t β^t=β^t∣t−1+Ktvt\hat{\beta}_t = \hat{\beta}_{t|t-1} + K_t v_t Pt=(1−Ktxt)Pt∣t−1P_t = (1 - K_t x_t) P_{t|t-1}

还是那个信噪比在管一切。ση2\sigma_\eta^2 大,滤波器把 beta 当作波动的、更信新观测;σε2\sigma_\varepsilon^2 大,特质噪声高,滤波器更信先验。日度收益上这个比值通常很小——beta 变化慢、特质噪声大——滤波给出重度平滑、只逐步适应的估计。月度数据上比值更高,beta 在低频显得更活跃,滤波适应也更快。

为什么不用滚动窗口回归?可以用,但带随机游走状态的卡尔曼滤波在数学上等价于指数衰减加权的回归:近期数据权重大,远期数据权重指数衰减,衰减率直接由信噪比控制。滤波器不需要你拍一个窗口大小,权重是模型自己算出来的——窗口大小这个超参数被两个有明确含义的方差取代了。

直接上代码:

import numpy as np
import pandas as pd

def kalman_beta(y, x, sigma_eta=0.01, sigma_eps=0.05):
    """随机游走 beta 带常数观测噪声。"""
    T = len(y)
    beta = 0.0
    P = 1.0  # diffuse 初始协方差
    
    betas = np.zeros(T)
    for t in range(T):
        # 预测(随机游走:beta 不变)
        beta_pred = beta
        P_pred = P + sigma_eta**2
        
        # 创新
        v = y[t] - x[t] * beta_pred
        F = x[t]**2 * P_pred + sigma_eps**2
        
        # 卡尔曼增益
        K = x[t] * P_pred / F
        
        # 更新
        beta = beta_pred + K * v
        P = (1 - K * x[t]) * P_pred
        
        betas[t] = beta
    
    return betas


betas = kalman_beta(stock_returns, market_returns, 
                    sigma_eta=0.005, sigma_eps=0.02)
plt.plot(betas); plt.title("卡尔曼的时变 beta"); plt.show()

对你的数据调 ση\sigma_\eta(状态噪声)和 σε\sigma_\varepsilon(观测噪声):ση\sigma_\eta 低给更平滑的 beta,ση\sigma_\eta 高让 beta 适应更快。

有效窗口:在线更新真正解决的问题

在交易系统里,你没奢侈到每来一个新价格就在全部历史上重估回归,这是计算上的理由。但更深的理由是概念漂移:市场状态在变,昨天股票和市场之间的关系明天未必成立。用全部历史等权估计 beta,等于给可能已经失效的远古观测和昨天的观测一样的话语权。

带 ση2>0\sigma_\eta^2 > 0 的卡尔曼滤波自动做指数降权。把滤波推到稳态可以算出这件事的力度:小信噪比下稳态增益约为 ση/σε\sigma_\eta / \sigma_\varepsilon,对应的有效窗口大致是

Neff≈2σεσηN_{\text{eff}} \approx \frac{2 \sigma_\varepsilon}{\sigma_\eta}

注意分子分母是标准差不是方差。比值 ση/σε\sigma_\eta / \sigma_\varepsilon 在 0.001 到 0.01 的量级时,有效窗口是 200 到 2000 个观测——日度数据上大约一到八年。这只是量级感受,具体数值随标的和频率变化,用你自己估出的方差算。反过来用也成立:你对”该记多久”有偏好,就能倒推出该设多大的 ση2\sigma_\eta^2。调高它,近期数据权重更大,滤波适应更快但更噪。

一个不那么讲究但常见的替代是遗忘因子。多维在线回归 yt=xt′βt+εty_t = \mathbf{x}_t' \boldsymbol{\beta}_t + \varepsilon_t 的通用更新形式是:

β^t=β^t−1+Kt(yt−xt′β^t−1)\hat{\boldsymbol{\beta}}_t = \hat{\boldsymbol{\beta}}_{t-1} + \mathbf{K}_t (y_t - \mathbf{x}_t' \hat{\boldsymbol{\beta}}_{t-1})

增益 Kt\mathbf{K}_t 控制系数适应多快,卡尔曼滤波给出最优增益:

Kt=Pt∣t−1xt/(xt′Pt∣t−1xt+σε2)\mathbf{K}_t = \mathbf{P}_{t|t-1} \mathbf{x}_t / (\mathbf{x}_t' \mathbf{P}_{t|t-1} \mathbf{x}_t + \sigma_\varepsilon^2)

随机游走动态下 Pt∣t−1=Pt−1+ση2I\mathbf{P}_{t|t-1} = \mathbf{P}_{t-1} + \sigma_\eta^2 \mathbf{I}。遗忘因子的做法是把这一步换成 Pt∣t−1=Pt−1/λ\mathbf{P}_{t|t-1} = \mathbf{P}_{t-1} / \lambda(λ<1\lambda < 1),更激进地稀释过去。自适应控制里常见,原则性不如随机游走模型,胜在好实现。

两个状态:配对交易的对冲比率

配对交易吃两个协整资产之间利差的均值回归。经典做法拟合一个静态对冲比率 β\beta,交易对均衡的偏离——问题跟静态 beta 一样:比率会漂。把时变 beta 模型加一个时变截距,状态从一维变二维:

βt+1=βt+ηt\beta_{t+1} = \beta_t + \eta_t yt=αt+βtxt+εty_t = \alpha_t + \beta_t x_t + \varepsilon_t

其中 yty_t 是资产 A 的价格,xtx_t 是资产 B 的价格。利差 yt−α^t−β^txty_t - \hat{\alpha}_t - \hat{\beta}_t x_t 在协整下应该平稳。交易规则照旧:利差超过 ±kσ^ε\pm k \hat{\sigma}_\varepsilon 建仓,回归零附近平仓。滤波器随新价格自动更新 β^t\hat{\beta}_t,不用每天重估。

但要认识到滤波器帮不了你的地方:协整关系可以整个崩掉。关系真有结构突变时,卡尔曼滤波照样给你一条平滑的 β^t\hat{\beta}_t——它的模型里没有”崩溃”这个词,它只会慢慢把断裂消化成漂移。盯创新序列:持续的大创新是滤波器在发散,也是关系崩溃的信号。这一点和前面协整文章里”检验是纯样本内的、抓不到断裂”是同一个警告的滤波版。

状态升维:动态因子模型

到这里状态都是一两个标量。把状态换成向量,就到了动态因子模型。先看静态版:

yt=Λft+et\mathbf{y}_t = \boldsymbol{\Lambda} \mathbf{f}_t + \mathbf{e}_t

yt\mathbf{y}_t 是 KK 维观测变量,ft\mathbf{f}_t 是 rr 维公共因子(r≪Kr \ll K),Λ\boldsymbol{\Lambda} 是 K×rK \times r 载荷,et\mathbf{e}_t 是特质噪声。因子通常用 PCA 提,隐含假设是因子结构不随时间变。动态版让因子自己有动态:

yt=Λtft+et\mathbf{y}_t = \boldsymbol{\Lambda}_t \mathbf{f}_t + \mathbf{e}_t ft+1=Φft+ηt\mathbf{f}_{t+1} = \boldsymbol{\Phi} \mathbf{f}_t + \boldsymbol{\eta}_t

Λ\boldsymbol{\Lambda} 常数、ft\mathbf{f}_t 走 VAR,就是静态载荷动态因子模型:状态是 ft\mathbf{f}_t,卡尔曼滤波给出因子的最优估计,载荷用 MLE。比如 K=100K = 100 个宏观序列提 3 个公共因子,状态维度 r×pr \times p(pp 是因子 VAR 的滞后阶),滤波可以同时估计因子和它们的动态。Λt\boldsymbol{\Lambda}_t 也动起来就是完全动态因子模型,难度陡增——因子和载荷都藏着——常见妥协是把几个”全局”因子固定为可观测或从特定序列估出,让其余时变。工程上的分界线:KK 大、状态维度中等,滤波很快;KK 非常大加时变载荷,就得上近似方法(两步 PCA 加卡尔曼,或 EM 在 E 步里跑卡尔曼)。

固定收益里有个成熟的向量状态应用:Diebold & Li (2006) 的动态 Nelson-Siegel 期限结构模型。到期 τ\tau 的收益率分解成三个因子:

yt(τ)=β1,t+β2,t(1−e−λτλτ)+β3,t(1−e−λτλτ−e−λτ)y_t(\tau) = \beta_{1,t} + \beta_{2,t} \left( \frac{1 - e^{-\lambda \tau}}{\lambda \tau} \right) + \beta_{3,t} \left( \frac{1 - e^{-\lambda \tau}}{\lambda \tau} - e^{-\lambda \tau} \right)

β1,t,β2,t,β3,t\beta_{1,t}, \beta_{2,t}, \beta_{3,t} 读作水平、斜率、曲率,λ\lambda 控制衰减。因子走 VAR(1):

βt=c+Fβt−1+ηt\boldsymbol{\beta}_t = \mathbf{c} + \mathbf{F} \boldsymbol{\beta}_{t-1} + \boldsymbol{\eta}_t

状态是 βt\boldsymbol{\beta}_t,观测是各到期的 yt(τ)y_t(\tau),滤波从收益率横截面里估出隐因子,拿去预测收益率曲线或研究期限溢价。中央银行和固定收益组合经理用它用得很勤。

混频数据是另一个方向的扩展。金融数据频率天然不齐:日度收益、周度指标、月度宏观。MIDAS(Mixed Data Sampling;Ghysels, Sinko & Valkanov, 2007)回归把低频被解释变量对高频回归子的分布滞后做回归,用简约的权重函数(比如指数衰减)把一长串高频滞后打包成少数几个参数,不用先做显式聚合——典型如用日度收益信息预测月度实现波动率。接上卡尔曼滤波:状态是回归系数,观测是低频目标,高频滞后按 MIDAS 权重打包成预测子,滤波随新数据在线更新系数。这条线扩展下去是 GARCH-MIDAS(Engle, Ghysels & Sohn, 2013):条件方差拆成短期 GARCH 成分和 MIDAS 驱动的长期成分。

放松线性:随机波动率

前面的扩展都保住了线性。随机波动率模型把对数波动率当作未观测的 AR(1),线性在这里保不住了:

rt=σtzt,zt∼N(0,1)r_t = \sigma_t z_t, \quad z_t \sim N(0, 1) log⁡σt2=μ+ϕ(log⁡σt−12−μ)+ηt,ηt∼N(0,ση2)\log \sigma_t^2 = \mu + \phi (\log \sigma_{t-1}^2 - \mu) + \eta_t, \quad \eta_t \sim N(0, \sigma_\eta^2)

状态是 log⁡σt2\log \sigma_t^2,观测是 rtr_t,但观测方程对状态非线性:

rt=exp⁡(12log⁡σt2)zt=σtztr_t = \exp(\tfrac{1}{2} \log \sigma_t^2) z_t = \sigma_t z_t

线性化硬上就是扩展卡尔曼滤波,效果一般。更好的路是粒子滤波——模拟一束波动率路径、按观测似然加权。Kim, Shephard & Chib (1998) 走了第三条路:用 offset 混合近似把问题拉回准线性框架,让随机波动率的 MLE 变得可行,本质上是带辅助混合成分的准卡尔曼方法。

选结构之前先想清楚状态是什么

状态空间框架是工具,不是模型。用它之前有三个选择要做:状态是什么(趋势、波动率、因子、beta、状态变量);状态怎么演化(随机游走、AR(1)、均值回归、切换);观测方程长什么样(线性、对数线性、门槛)。每个选择都有经济内容。别盲目套卡尔曼滤波——想清楚隐藏状态代表什么、凭什么按你指定的方式演化。想不清楚就退回母模型:随机游走加噪声,两个参数,MLE 能估,错也错得明白。

实现的坑

模型选对了,实现还能翻车。这几条按出现频率排:

  1. 数值负定。协方差矩阵 Pt\mathbf{P}_t 会因舍入误差变成负定。用协方差更新的 Joseph 形式:
Pt=(I−KtZt)Pt∣t−1(I−KtZt)′+KtHtKt′\mathbf{P}_t = (\mathbf{I} - \mathbf{K}_t \mathbf{Z}_t) \mathbf{P}_{t|t-1} (\mathbf{I} - \mathbf{K}_t \mathbf{Z}_t)' + \mathbf{K}_t \mathbf{H}_t \mathbf{K}_t'

代数上等价于标准形式,数值上稳健得多。

  1. 初始条件。错误的初始条件要很多时步才洗得掉,状态过程持续性越高越久。diffuse 初始化要用得小心,或者用精确 diffuse 滤波器。
  2. 离群点。滤波器会”信任”离群点,单个离群点能扭曲 Pt\mathbf{P}_t 很多个后续时步。用稳健滤波或手动降权。
  3. 缺失数据。缺口多时状态协方差会无界增长,给 P0\mathbf{P}_0 设合理先验。
  4. 噪声模型错。观测噪声设错(比如按高斯建模但数据是 Student-tt),滤波仍是最优线性滤波、点估计通常还能看,但不确定性量化是错的。合适的话换肥尾观测噪声模型。
  5. 识别。状态空间模型没约束不可识别:随机游走加噪声模型里,(ση2,σε2)(\sigma_\eta^2, \sigma_\varepsilon^2) 和 (cση2,cσε2)(c \sigma_\eta^2, c \sigma_\varepsilon^2) 对任意 c>0c > 0 给出同分布的观测。约束一个方差固定尺度。

跟替代方案摆在一起

跟滚动窗口回归比,前面说过了:数学上等价于指数衰减加权,衰减率由信噪比决定,计算上还更便宜(不用每个窗口重算)。跟指数平滑比:简单指数平滑(Holt-Winters 一族)是带局部水平或局部线性趋势加季节的结构时间序列的特例,卡尔曼滤波算的是同一个平滑估计——显式状态空间的好处是能往上加更复杂的动态(多重季节性、外生回归子)而框架不变。

跟固定参数回归比要诚实一点:如果系数真是常数,固定参数 OLS 更有效,允许系数漂移是要付效率代价的。你能捍卫系数的平稳性就用 OLS,不能就用卡尔曼——这不是卡尔曼无条件更好的问题,是你对世界的假设决定工具。跟机器学习比也是同一个逻辑:RNN、LSTM、transformer 能从数据里学时变模式,更灵活,但要更多数据、更难解释、不确定性量化不干净。小数据集加清晰的状态空间结构,卡尔曼赢;大数据集加丰富的非线性模式,神经网络可能赢。

收尾:这其实是在线学习

卡尔曼滤波是在线学习——机器学习里关心序贯更新的那个子领域——的基础算法之一。同样的”预测、观测、算误差、按增益修正”递推出现在强化学习的 TD(λ\lambda) 值函数估计里,出现在在线凸优化的各种遗憾最小化算法里,出现在共轭先验的序贯贝叶斯更新里。这不是巧合:卡尔曼滤波就是线性高斯模型的闭式贝叶斯更新,是一个特定在线学习问题的精确解。把它吃透,在线学习的很大一块你已经懂了,哪怕算法表面长得不一样。

参考文献

  • Diebold, F. X., & Li, C. (2006). Forecasting the term structure of government bond yields. Journal of Econometrics, 130(2), 337-364.
  • Durbin, J., & Koopman, S. J. (2012). Time Series Analysis by State Space Methods (2nd ed.). Oxford University Press.
  • Fama, E. F., & MacBeth, J. D. (1973). Risk, return, and equilibrium: Empirical tests. Journal of Political Economy, 81(3), 607-636.
  • Garba, M. (2016). Time-varying beta. Quantitative Finance, 16(6), 867-878.
  • Ghysels, E., Sinko, A., & Valkanov, R. (2007). MIDAS regressions: Further results and new directions. Econometric Reviews, 26(1), 53-90.
  • Hamilton, J. D. (1994). Time Series Analysis. Princeton University Press. Ch. 13.
  • Harvey, A. C. (1989). Forecasting, Structural Time Series Models and the Kalman Filter. Cambridge University Press.
  • Kim, S., Shephard, N., & Chib, S. (1998). Stochastic volatility: Likelihood inference and comparison with ARCH models. Review of Economic Studies, 65(3), 361-393.
  • Tsay, R. S. (2010). Analysis of Financial Time Series (3rd ed.). Wiley. Ch. 11.
  • Engle, R. F., Ghysels, E., & Sohn, B. (2013). Stock market volatility and macroeconomic fundamentals. Review of Economics and Statistics, 95(3), 776-797.