一、配对交易基础:什么是配对交易、统计套利原理、协整与相关性、均值回归策略
说实话,我第一次接触配对交易是在2015年。当时我在做ETF套利,发现两只银行股经常同涨同跌,但偶尔会拉开差距。我就在想——能不能等它们拉开时做空强的、做多弱的,等它们重新靠拢再平仓?
后来我才知道,这玩意儿有个正式名字,叫配对交易。说白了,就是利用两个相关资产之间的价差波动来赚钱。你不需要判断市场涨跌,只需要判断它们之间的关系会不会回归。
1.1 什么是配对交易
配对交易的核心思想很简单:找到两只走势高度相关的股票(或任何资产),当它们的价差偏离正常范围时,做空强势的、做多弱势的,赌它们会重新回到均衡状态。
举个例子。我做过一个经典的配对:可口可乐和百事可乐。这两家公司业务相似,股价长期走势几乎同步。但有时候,可口可乐因为某个财报超预期涨了3%,百事只涨了0.5%。这时候价差就拉大了。我的策略是:卖出可口可乐,买入百事可乐,等它们价差回归后平仓。
嗯,这里要注意——配对交易不是无风险套利。它赌的是统计上的回归,而不是确定性的回归。万一基本面变了,价差可能永远回不来。
核心要点:
- 配对交易是市场中性策略——不依赖大盘涨跌
- 赚的是价差回归的钱,不是趋势的钱
- 需要两个资产之间有稳定的统计关系
1.2 统计套利原理
统计套利,听起来高大上,其实原理不复杂。它基于一个假设:资产价格在短期内可能偏离,但长期会回归统计上的均衡。
我习惯把统计套利分成三步走:
- 找关系——找到两个或多个资产之间的统计规律
- 算阈值——确定什么时候算"偏离"(比如价差超过2个标准差)
- 做交易——偏离时开仓,回归时平仓
你想想看,这跟传统套利有什么区别?传统套利是确定性的——比如同一只股票在不同交易所的价差,你买入低价、卖出高价,稳赚。但统计套利是概率性的——你只能保证"大概率"会回归,不是100%。
我曾经踩过的坑:
2018年我做了一组能源股的配对,回测表现特别好。结果实盘时,因为一家公司突然宣布转型新能源,价差直接崩了,再也没回来。那次亏损让我明白——统计套利的前提是"结构稳定",一旦结构变了,历史规律就失效了。
1.3 协整与相关性
很多人搞混这两个概念。我刚开始做配对交易时也犯过这个错——只看相关性,不看协整。
相关性衡量的是两个变量之间的线性关系强度。相关系数接近1或-1,说明它们同涨同跌。但相关性有个大问题:它只看短期波动,不关心长期关系。
协整就不一样了。它衡量的是两个时间序列之间是否存在长期均衡关系。即使两个序列各自随机游走(非平稳),它们的线性组合可能是平稳的——这就是协整。
举个例子。一个醉汉牵着一条狗走路。醉汉的路径是随机的,狗的路径也是随机的,但狗绳的长度是固定的。醉汉和狗的位置就是协整关系——它们可能到处乱跑,但距离始终在绳子范围内。
| 指标 | 相关性 | 协整 |
|---|---|---|
| 衡量什么 | 短期线性关系 | 长期均衡关系 |
| 适用场景 | 趋势跟踪 | 配对交易 |
| 常见误区 | 高相关≠协整 | 需要单位根检验 |
| 检验方法 | Pearson相关系数 | Engle-Granger检验 |
我的经验:
我建议先算相关性做初筛,再用协整检验做确认。相关性高的不一定协整,但协整的一定相关性高(至少长期来看)。别偷懒跳过协整检验——我见过太多人只看相关性就开干,结果亏得底朝天。
1.4 均值回归策略
均值回归是配对交易的底层逻辑。它假设价差会在均值附近波动,偏离越大,回归的概率越高。
具体怎么做?我一般用以下步骤:
- 计算价差:价差 = 资产A价格 - β × 资产B价格(β是协整系数)
- 标准化:把价差转换成Z-score,方便设定阈值
- 设定开仓阈值:比如Z-score超过2或低于-2时开仓
- 设定平仓阈值:Z-score回归到0附近时平仓
- 设定止损:Z-score超过3或-3时止损
下面是一个简单的Python示例,展示如何计算Z-score并生成交易信号:
import numpy as np
import pandas as pd
from statsmodels.tsa.stattools import coint
# 假设我们有两只股票的价格数据
# price_a, price_b 是pandas Series
# 1. 计算协整系数
def calculate_beta(price_a, price_b):
# 用OLS回归估计beta
cov = np.cov(price_a, price_b)
beta = cov[0,1] / cov[1,1]
return beta
# 2. 计算价差和Z-score
def calculate_spread_zscore(price_a, price_b, beta, window=20):
spread = price_a - beta * price_b
zscore = (spread - spread.rolling(window).mean()) / spread.rolling(window).std()
return spread, zscore
# 3. 生成交易信号
def generate_signals(zscore, entry_threshold=2.0, exit_threshold=0.5):
signals = pd.Series(index=zscore.index, data=0)
# 开仓信号
signals[zscore > entry_threshold] = -1 # 做空价差
signals[zscore < -entry_threshold] = 1 # 做多价差
# 平仓信号
signals[abs(zscore) < exit_threshold] = 0
return signals
嗯,这里有个细节——窗口大小的选择很关键。窗口太小,Z-score波动太频繁,容易产生虚假信号。窗口太大,反应太慢,可能错过最佳开仓点。我一般用20-60个交易日,具体看品种的波动特性。
均值回归策略的关键参数:
- 窗口期:计算均值和标准差的时间窗口
- 开仓阈值:一般1.5-2.5个标准差
- 平仓阈值:一般0-0.5个标准差
- 止损阈值:一般3-4个标准差
- 持仓周期:通常3-20个交易日
最后说一句——均值回归策略在震荡市中表现最好。如果市场出现单边趋势,或者配对的基本面发生重大变化,策略就会失效。所以,永远要设止损,别死扛。