配对交易里那个被对冲掉的部分——价差(spread)——它的「脾气」决定了一切。价差今天偏离均值 5%,你是该立刻加仓赌它回去,还是等它再走远一点?答案只取决于一件事:它回归均值有多快。
这个问题在波动率建模、利率期限结构、甚至订单流失衡里反复出现。给它一个数学身体,就是 Ornstein-Uhlenbeck(OU)过程;而给它一把尺子,就是本文的主角——半衰期(half-life)。
一、OU 过程:把「均值回归」写成一个方程#
标准 OU 是一个带「弹性」的随机微分方程:
逐项读:
- 是长期均值(中枢);
- 是回归速度: 越大,偏离被拉回越快;
- 是瞬时冲击(布朗运动乘以波动幅度)。
最妙的是,解这方程的期望路径是简单的指数衰减:
也就是说,任意时刻偏离均值的部分,都按 指数式缩水。这条曲线不依赖任何随机项——它描述的是期望路径,真实样本会在它周围抖动,但中枢与衰减率由 完全决定,所以 κ 才成为可估计的唯一自由度。
二、半衰期:给回归速度一个可解释的数字#
「 到底快不快?」没人直觉得了。把衰减和「离均值的距离减半」绑在一起,就得到半衰期:
含义直白:每过 HL 个单位时间,当前偏离均值的距离就会缩小一半。 时 步——如果你按日度建模,就是大约 9 个交易日回归一半。这把「回归速度」翻译成了任何人都能用的时标。

一个常被忽略的孪生结论:OU 的稳态方差也收敛到 ——回归越快(κ 大),长期波动越小。这意味着快回归的价差不仅「回得急」,长期也「更安静」,两类信息对仓位规模是同向的,可以合并成一个仓位标量。和 AR(1) 的衰减 对照会更直觉:离散步长下 ,所以「每步乘 b」就是「每 时间乘 」——连续与离散在此严丝合缝地接上,后面用回归斜率反推 κ 正是利用这条桥。但这只在 κ 恒定、无跳的理想假设下成立,跳变与时变 κ 怎么拆,见第六节。
三、实战怎么估:把 OU 离散成 AR(1)#
真实数据不是连续 SDE,而是离散的时间序列。把 OU 用步长 离散化:
这正是 AR(1) 自回归 的形式!于是 与半衰期可以纯粹由回归斜率反推:
只要对 做 OLS,拿到斜率 ,就能算出一切。

四、Python:模拟、拟合、读出半衰期#
下面这段代码与三张配图完全对应,是自洽合成数据(OU 离散化 + 一条对照随机游走),仅用于演示方法;真实落地请用实际价差序列(见文末)。
import numpy as np
def simulate_ou(kappa, theta=0.0, sigma=0.10, dt=1.0, T=600, seed=None):
rng = np.random.default_rng(seed)
b = np.exp(-kappa * dt)
x = np.zeros(T); x[0] = theta + sigma * rng.normal()
for t in range(1, T):
x[t] = theta + b * (x[t-1] - theta) + sigma * np.sqrt(dt) * rng.normal()
return x, b
def ar1_slope(x):
"""OLS: x_t = a + b*x_{t-1} + e → 返回 (截距, 斜率b, 斜率标准误)"""
y = x[1:]; X = np.column_stack([np.ones_like(x[:-1]), x[:-1]])
beta, *_ = np.linalg.lstsq(X, y, rcond=None)
a, b = beta
resid = y - X @ beta
seb = np.sqrt((resid @ resid) / (len(y) - 2) /
np.sum((x[:-1] - x[:-1].mean()) ** 2))
return a, b, seb
# 真实 κ=0.15 → 理论半衰期 ln2/0.15 ≈ 4.6 步
x, _ = simulate_ou(0.15, T=600, seed=21)
a, b, seb = ar1_slope(x)
kappa = -np.log(b) # dt = 1
half = np.log(2) / kappa
print(f"b={b:.3f}±{seb:.3f} κ={kappa:.3f} half-life={half:.2f}")python跑出来 、、半衰期约 5.6 步——和理论值 4.6 同量级,差异来自有限样本的估计噪声(这就是第六节要说的陷阱)。
手算复核与一个被低估的用法#
把 代回公式自己算一遍:(),于是 步——和代码输出对得上。这一步必须能手算复核,因为 是分母上的对数,任何把 算错的符号或数量级错误,都会被半衰期反比放大成离谱结论。
半衰期真正的价值,是把它接成持有期设计器。由期望衰减 可知,持有 步后偏离均值被拉回的比例是:
代入 得 0.5(定义); 得 0.75; 得 0.875。也就是说:持有约两个半衰期,你就吃到了四分之三的均值回归力道;再往后持有,边际回归收益迅速变薄,反而开始累积冲击成本。配对交易里「价差偏离几个标准差时建仓、回到中枢附近就平」的阈值,本质上就是用 HL 把「几个 σ 偏离 ≈ 几个 HL 的等待」翻译成了具体数字。
五、半衰期随 κ 变化:一张图记住数量级#
半衰期与回归速度是反比:κ 翻倍,HL 减半;κ 趋近 0,HL 爆炸。这条曲线值得刻进肌肉记忆:

对照两个极端很重要:
- 随机游走:等价于 ,即 ,半衰期无穷大——根本没有均值可回归。如果你的价差其实是个随机游走,那「等它回归」就是等一个永远不会来的价。
- 过快回归(κ 很大):HL 短到几个 tick,那已经不是统计套利,而是做市/高频的游戏,成本结构完全不同。
六、实盘三大真实陷阱#
陷阱一:先问「它到底回不回归」——单位根检验。 OU 的一切前提是序列平稳。很多所谓「价差」在样本内看着挺均值回归,样本外却是带漂移的随机游走。动手估 HL 之前,先做 ADF/KPSS 检验确认平稳;否则你算出的半衰期是个毫无意义的数字(∞ 的近似)。
陷阱二:OU 假设「线性、连续、无跳」。 真实价差会被跳变打断——财报、停牌、指数调样会让价差瞬间跳到新平台,OU 的平滑弹性捕捉不到。加上 κ 本身可能时变(牛市的价差比危机里黏得多),用全样本一个固定 κ 去估,等于用平均气温指导今天穿什么。稳健做法是用滚动窗口或状态切换模型估时变 HL。
陷阱三:小样本下 b 的偏差会骗你。 上节的 5.6 vs 4.6 已经显示,样本不够长、噪声不够小,OLS 斜率就会系统性偏一点,HL 跟着偏。更阴险的是估计误差会被半衰期反比放大:κ 越小(HL 越长),ln(b) 越靠近 0, denominator 上的一点点误差都会被除成很大的 HL 抖动。长 HL 的资产,HL 几乎不可靠地估计。
陷阱四:单一 HL 掩盖了多尺度。 真实价差常常同时挂着「快回归 + 慢漂移」两层:OU 层在几个 HL 内把偏离拉回,但还有个慢趋势在悄悄挪动中枢。你用全样本估出的一个 κ,其实是这两层的混血,会高估快回归、低估慢漂移。实战里要把序列先做多尺度分解(或对中枢本身做滚动估计),再分别读 HL——否则你按单 HL 设的止盈带,会被慢趋势一层层推出去再拉回,白白挨来回。
七、落地路径与诚实结论#
真实复现时,把合成序列换成:
- 价差来源:协整配对的两腿残差、ETF 折溢价、VIX 与实现波动之差、利率期限利差等;
- 估计:对平稳价差做滚动 AR(1) 拿时变 κ,再用 转成持有期与仓位节奏的参考;
- 用法:HL 不是买卖信号,而是时间尺度的校准器——HL 越长,越该降低调仓频率、放宽止盈带,别用高频的耐心去熬长 HL 的价差。
- 跨资产:同一把尺子能跨资产比——波动率目标里的 vol 本身有 OU 式均值回复、利率期限斜率也是,分别读出 HL 后,哪个资产「回归更急」一目了然,组合里该给谁更短的再平衡周期也有据可依。
- 给 HL 一个置信区间:单点估计没有意义。用 bootstrap 或滚动窗口把 HL 的重抽样分布画出来,若 90% 区间跨了一个数量级,那这个 HL 只配当「量级直觉」,不配进任何硬性阈值。
结论:OU 过程把模糊的「会回归」变成可估计、可比较的 与半衰期。它是配对交易和波动率建模的默认身体,但身体有前提——平稳、无跳、κ 恒定。落到自己数据上,先证伪单位根、再谈半衰期,否则你量到的只是一段恰好看起来会回家的随机游走。