第三章 统计套利基础:协整与均值回归

各位好,欢迎来到第三章。

前两章我们聊了复杂系统的一些基本概念,以及市场里那些看似随机、实则有序的混沌现象。今天,我们终于要进入一个非常具体的实战领域——统计套利。

说白了,统计套利就是利用数学工具,找到两个或多个资产之间那种「长期稳定、短期偏离」的关系。然后,在它们偏离的时候下注,等它们回归的时候收钱。

嗯,听起来是不是有点像「捡漏」?没错,就是捡市场的漏。

3.1 协整:两个时间序列的「舞步」

要理解统计套利,首先得理解协整。

我记得刚入行那会儿,有个老交易员跟我说:「你看这两只股票,走势就像一对舞伴,虽然各自跳得乱七八糟,但步调总是一致的。」我当时觉得这比喻挺玄乎,后来学了协整,才发现人家说的就是数学。

协整的定义:如果两个非平稳的时间序列(比如股价),它们的某个线性组合是平稳的,那我们就说这两个序列是协整的。

举个例子:

  • 序列A:随机游走(非平稳)
  • 序列B:随机游走(非平稳)
  • 但 A - 2*B 是平稳的(围绕一个均值波动)

那A和B就是协整的。

为什么会这样?因为这两个序列背后有一个共同的「隐藏因子」在驱动它们。比如两家同行业的公司,受同样的宏观经济影响,长期来看它们的价差就会保持稳定。

关键点:协整 ≠ 相关性。

相关性高不代表协整。两只股票可能高度相关,但价差却越走越远,那就不适合做配对交易。我见过不少新手上来就找相关系数高的股票,结果亏得一塌糊涂。原因就是——它们不协整。

3.2 均值回归:市场的「橡皮筋」效应

协整给了我们一个「长期关系」,而均值回归给了我们「交易信号」。

想象一下,你把两个协整的资产绑在一起,中间连一根橡皮筋。当它们偏离太远时,橡皮筋就会把它们拉回来。这个「拉回来」的过程,就是均值回归。

我个人习惯用「价差」来观察这个现象。价差 = 资产A的价格 - β * 资产B的价格。这里的β,就是协整系数。

当价差偏离均值超过某个阈值(比如2倍标准差),我们就认为出现了交易机会:

  • 价差过高 → 做空价差(卖A买B)
  • 价差过低 → 做多价差(买A卖B)

等它回归到均值附近,平仓获利。

避坑指南:我曾经在2015年股灾期间做过一个配对交易,价差偏离到了4倍标准差,我以为机会来了,重仓杀入。结果呢?价差继续偏离,直接爆仓。

后来我才明白:均值回归不是必然发生的。极端行情下,橡皮筋可能会断。所以,止损和仓位管理永远是第一位的。

3.3 配对交易策略的数学框架

好了,理论讲完了,我们来搭一个完整的数学框架。

步骤1:选择配对

通常在同行业、同板块中寻找。比如:可口可乐 vs 百事可乐,或者工商银行 vs 建设银行。

步骤2:检验协整

用Engle-Granger两步法或Johansen检验。我个人常用的是Engle-Granger:

  1. 对两个序列做回归:Y = α + βX + ε
  2. 对残差ε做单位根检验(ADF检验)
  3. 如果残差平稳,则协整成立

步骤3:确定交易阈值

计算价差的均值和标准差。通常设置:

  • 开仓阈值:均值 ± 2倍标准差
  • 平仓阈值:均值 ± 0.5倍标准差
  • 止损阈值:均值 ± 3倍标准差

步骤4:执行交易

当价差触及开仓阈值时,建立头寸。回归到平仓阈值时,平仓。

数学表达

设价差序列为 S_t = P_A_t - β * P_B_t

交易信号:

  • 如果 S_t > μ + 2σ → 做空价差
  • 如果 S_t < μ - 2σ → 做多价差
  • 如果 |S_t - μ| < 0.5σ → 平仓

3.4 用Python实现一个简单的配对交易回测

纸上谈兵没意思,我们来写点真家伙。

下面这个例子,我用的是招商银行(600036)和兴业银行(601166)的历史数据。这两家都是股份制银行,业务结构相似,理论上应该协整。

import pandas as pd
import numpy as np
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller
import matplotlib.pyplot as plt

# 1. 加载数据(假设你已经有了两个DataFrame)
# 这里用模拟数据演示
np.random.seed(42)
dates = pd.date_range('2020-01-01', periods=500, freq='D')
# 模拟两个协整序列
common_trend = np.cumsum(np.random.randn(500)) * 0.01
stock_a = 100 + common_trend + np.random.randn(500) * 0.5
stock_b = 100 + common_trend * 0.8 + np.random.randn(500) * 0.3

df = pd.DataFrame({'A': stock_a, 'B': stock_b}, index=dates)

# 2. 检验协整
def check_cointegration(series1, series2):
    # 回归
    X = sm.add_constant(series2)
    model = sm.OLS(series1, X).fit()
    beta = model.params[1]
    residuals = model.resid
    
    # ADF检验
    adf_result = adfuller(residuals)
    p_value = adf_result[1]
    
    return beta, p_value

beta, p_val = check_cointegration(df['A'], df['B'])
print(f'协整系数 β: {beta:.4f}')
print(f'ADF检验 p值: {p_val:.4f}')

if p_val < 0.05:
    print('协整关系成立')
else:
    print('协整关系不成立')

# 3. 计算价差
df['spread'] = df['A'] - beta * df['B']
mean_spread = df['spread'].mean()
std_spread = df['spread'].std()

# 4. 生成交易信号
df['z_score'] = (df['spread'] - mean_spread) / std_spread
df['signal'] = 0
df.loc[df['z_score'] > 2, 'signal'] = -1  # 做空价差
df.loc[df['z_score'] < -2, 'signal'] = 1  # 做多价差
df.loc[abs(df['z_score']) < 0.5, 'signal'] = 0  # 平仓

# 5. 回测(简化版:假设每次交易1单位)
df['position'] = df['signal'].shift(1)  # 第二天开盘执行
df['return'] = df['position'] * df['spread'].diff()
df['cum_return'] = (1 + df['return']).cumprod()

# 6. 结果
print(f'累计收益率: {df["cum_return"].iloc[-1]:.4f}')
print(f'夏普比率: {df["return"].mean() / df["return"].std() * np.sqrt(252):.4f}')

# 画图
plt.figure(figsize=(12, 8))
plt.subplot(2, 1, 1)
plt.plot(df.index, df['spread'], label='价差')
plt.axhline(mean_spread, color='black', linestyle='--')
plt.axhline(mean_spread + 2*std_spread, color='red', linestyle='--')
plt.axhline(mean_spread - 2*std_spread, color='green', linestyle='--')
plt.legend()

plt.subplot(2, 1, 2)
plt.plot(df.index, df['cum_return'], label='累计收益', color='orange')
plt.legend()
plt.show()

注意:上面的代码是简化版,实际回测要考虑:

  • 交易成本(佣金、滑点)
  • 资金管理(每次交易多少仓位)
  • 动态更新协整系数(滚动窗口)
  • 多品种配对(不止一对)

我曾经在实盘中发现,如果不考虑滑点,回测曲线漂亮得像假的一样。一上实盘,直接打回原形。所以,回测一定要保守再保守。

3.5 本章知识体系图

下面这张图,是我自己画的一个知识结构,帮你理清思路:

统计套利知识体系 协整 均值回归 配对交易 Engle-Granger两步法 ADF检验残差平稳性 价差分析 均值 ± k*标准差 交易执行 开仓/平仓/止损 Python实现 回测框架 实盘注意事项 核心:协整是基础,回归是信号,执行是关键

3.6 一些实战中的坑

最后,分享几个我踩过的坑,希望能帮你省点学费:

表现 解决办法
协整关系失效 价差不再回归,越走越远 定期重新检验协整,设置止损
过度拟合 回测漂亮,实盘拉胯 使用样本外数据验证,减少参数
交易成本 频繁交易吃掉利润 提高阈值,降低交易频率
流动性不足 无法按预期价格成交 选择高流动性品种,避免小盘股

我的建议:刚开始做配对交易,别想着赚大钱。先用模拟盘跑三个月,把各种坑都踩一遍。等你对策略的「脾性」摸透了,再上小资金实盘。

记住:统计套利赚的是「概率」的钱,不是「确定性」的钱。你可能会连续亏损10次,但只要第11次赚回来,整体就是盈利的。关键是——你得活到第11次。


公众号:蓝海资料掘金营,微信deep3321