配对交易(pair trading)是量化入门第一课:找两只走势绑定的股票,价差一拉大就反向开仓。但真实市场里,能绑定的往往不止两只——同一产业链的上下游、同一板块的权重股、汇率三角(EUR/USD、USD/JPY、EUR/JPY),常常是三只一起共享一个”共同趋势”。两两配对会漏掉信息,还会因为选哪一对而结果不稳定。
Johansen (1991) 把协整从”二元”推广到”多元”:它一次性检验 个 序列里到底有几个协整关系,并把每个关系写成一个协整向量 。本文要讲清三件事,并用可复现代码演示:
- 多元协整的模型框架(VECM 与 );
- Johansen 的两个检验——迹检验与最大特征值检验;
- 拿到 之后,怎么把”三组一起”做成套利组合。
它也是外汇三角套利、ETF 篮子套利背后同一套统计语言。
一、为什么二元配对不够#
Engle-Granger 两步法只处理两只资产:对 回归得残差,再做 ADF 看残差稳不稳。问题有三:
- 信息浪费:三只资产 共享一个趋势,单独看 的残差可能勉强平稳、 又不平稳,你不知道该信哪对;
- 不对称:回归里谁是”被解释变量”会影响结果(对 回归 和反过来不一样);
- 无法处理多个共同趋势:当存在不止一个协整关系时,二元框架根本表达不了。
Johansen 直接把 个资产放进一个向量,用极大似然一次性把结构拆干净。
二、向量误差修正模型(VECM)#
假设 个价格 都是 (一阶单整,自身非平稳,但存在平稳的线性组合)。Johansen 从 VAR 出发,写成误差修正形式:
- 是 的协整向量矩阵:每一列是一个协整关系, 平稳;
- 就是协整秩(有几个平稳组合);
- 是 的调整速度矩阵:描述每个资产以多快速度被”拉回”均衡。
直观理解:如果 偏离了 0(价差走阔), 就会推动 把它拉回来——这就是”误差修正”。 的对角元越负,回复越快。
的符号也有含义:若某个资产在 里对应正、其它为负,说明当价差走阔时,是这只资产在”被推着”往均衡回(它主导修复);若几项同号,则更像共同的外生冲击在驱动。看 能知道”到底是谁在维持这个均衡关系”。
接下来 Johansen 要回答两个具体问题: 等于几? 以及 长什么样?
三、Johansen 检验:广义特征值分解#
核心是把 的秩 变成可检验的统计量。做法:
- 取 对常数项回归的残差 ,以及 对常数项回归的残差 ;
- 算三个矩矩阵 ;
- 解广义特征值问题 ,其中 ;
- 得到 个特征值 。
⚠️ 一个新手必踩的坑:残差 是 对常数项回归的残差,不能把 也当回归元放进去——否则协整信息会从 里被抹掉, 直接变 0,特征值全为 0,检验彻底失效。
特征值越大,说明对应的方向越”平稳”(越像个协整关系)。Johansen 基于这些特征值构造两个检验:
- 迹检验(Trace):,检验”协整秩 ”;
- 最大特征值检验(Max-Eigen):,只检验”第 个特征值是否为 0”。
把算出的统计量和 Osterwald-Lenum (1992) 的渐近临界值比,就能定出 。
import numpy as np
import scipy.linalg as sla
def simulate_vecm(T=2500, seed=42):
rng = np.random.default_rng(seed)
beta = np.array([1.0, -0.5, -0.5]) # 真实协整向量
alpha = np.array([-0.06, 0.03, 0.03]) # 调整速度
Pi = np.outer(alpha, beta)
X = np.zeros((T, 3)); X[0] = rng.normal(0, 0.1, 3)
for t in range(1, T):
eps = rng.multivariate_normal(np.zeros(3), np.diag([0.01,0.01,0.01]))
X[t] = X[t-1] + Pi @ X[t-1] + eps
return X
def johansen(X):
dX = np.diff(X, axis=0); Xlag = X[:-1]; TT = dX.shape[0]
R0 = dX - dX.mean(0); R1 = Xlag - Xlag.mean(0)
S00 = R0.T@R0/TT; S11 = R1.T@R1/TT; S01 = R0.T@R1/TT
A = S01.T @ np.linalg.inv(S00) @ S01
lam, beta = sla.eig(A, S11); lam = np.real(lam)
order = np.argsort(lam)[::-1]; lam = lam[order]; beta = beta[:, order]
beta_norm = beta / beta[0, :]
b1 = beta[:, :1]
alpha = S01 @ b1 @ np.linalg.inv(b1.T @ S11 @ b1)
trace = [-TT*np.sum(np.log(1 - lam[r:])) for r in range(3)]
maxe = [-TT*np.log(1 - lam[r]) for r in range(3)]
return lam, beta_norm, alpha, np.array(trace), np.array(maxe)
X = simulate_vecm()
lam, beta_norm, alpha, trace, maxe = johansen(X)
print("特征值:", np.round(lam, 4))
print("beta(归一化):", np.round(beta_norm[:, 0], 4))
print("迹统计量 r<=0,1,2:", np.round(trace, 2))
print("最大特征值 r=0,1,2:", np.round(maxe, 2))python跑出来( 为三资产、T=2500):
特征值: [0.0527 0.0019 0.0016]
beta(归一化): [ 1. -0.5104 -0.4779]
迹统计量 r<=0,1,2: [144.04 8.81 3.93]
最大特征值 r=0,1,2: [135.23 4.87 3.93]plaintext临界值(95%):迹检验 ;最大特征值 。
判读:
- 迹检验:(拒绝""),但 (不拒绝"")→ 协整秩 ;
- 最大特征值:,但 → 同样 。
两个检验一致:三个资产里存在恰好一个协整关系。而且估计出的 ,和模拟时埋的真值 几乎重合——说明 Johansen 真的把”哪三个权重组合在一起才平稳”找出来了。



四、从 β 到三组一起的套利#
拿到 ,就能构造三腿组合(价差):
是平稳的——它不会像单只价格那样一路漂移,而是在均值附近来回晃。估计出的误差修正速度 ,半衰期约 5 期,说明拉大之后几个交易日就能回复。
套利规则很直接:
- 当 的 z-score 冲过 (组合被高估):卖 、买 份 、买 份 ;
- 当 z-score 跌破 (被低估):反向;
- 回到 0 附近平仓。
注意三个腿的头寸是按 的权重绑定的——这正是”三组一起”和”两两配对”的本质区别:你不是在交易某两只的相对价格,而是在交易一个三维空间里的均衡偏离,且每一腿的头寸比例由统计估计给出,不是拍脑袋。
经典例子是外汇三角:EUR/USD、USD/JPY、EUR/JPY 三者满足无套利三角关系,任一边的偏离都会被三边套利瞬时抹平——这正是 Johansen 在真实市场里最干净的应用场景之一。

五、真实陷阱(别拿到 β 就冲进去)#
1. 先检验单整性,别拿伪协整当真。 Johansen 的前提是变量都是 且协整。如果某个资产其实是 (本身平稳),或者存在确定性趋势没处理,结论会全盘错。正式流程要先做 ADF/PP 单位根检验。
2. 结构突变会让协整关系”断裂”。 2008、2020、监管政策变化,都可能让原来的产业链关系失效。用全样本估出的 在样本内漂亮,样本外可能早已漂移。实战要滚动窗口重估 ,并监控 是否稳定。
3. β 的”识别”问题。 Johansen 给出的特征向量只确定到”空间”层面;如果有多个协整关系(),哪个向量对应哪个经济含义需要额外约束(just-identified / over-identified)才能解释。本文 相对简单,但多关系时别以为随便归一化就行。
4. 小样本与 size distortion。 渐近临界值在小 T、近单位根时严重失真,检验会过度拒绝(假阳性)。T=2500 已经比较稳,但若用日频短样本(T 几百),最好用 bootstrap 临界值或 Bartlett 小样本修正。
5. 交易成本吃光统计套利。 三组一起意味着三倍的手续费、买卖价差和冲击成本。协整价差的均值回复幅度往往只有几个 bp,单边交易成本就可能吞掉大部分收益。回测必须按真实 tick 级成本核算,别只看价差 z-score 的”理论净值”。
6. 对冲比例≠无风险。 用 权重建仓只是统计意义上的”市场中性”,不是真的无风险——共同趋势的临时冲击、个股特异性风险、流动性同时枯竭,都会让三腿在极端时一起亏。
7. 近共线让 β 不稳定。 当三只资产高度相关(比如同板块三只银行股),协整向量在数值上接近奇异, 的估计对样本极敏感,稍有不同就给出差别很大的权重。这时应先做主成分或聚类降维,别直接把高度相关的标的塞进 Johansen。
六、小结#
- 两两配对只利用了二元信息;Johansen 把 个资产放进 VECM,一次性给出协整秩 、协整向量 和调整速度 (比 Engle-Granger 信息更全、且不受回归方向影响);
- 检验靠广义特征值分解出的 ,用迹检验和最大特征值检验两个角度交叉确认 ;
- 拿到 就能构造多腿价差做均值回复,头寸比例由统计估计给出——这是”三组一起套利”的严谨版本;
- 落地前务必处理单位根前置检验、结构突变、小样本失真、交易成本这四类真实陷阱。
附:本文所有图表与检验数值均来自上方可运行代码(VECM 模拟 + Johansen 广义特征值分解 + 迹/最大特征值检验),参数与结果一致,可直接复现。