第 5 章 · 03 配对与套利:配对交易、ETF 配对、配对切换 本节摘要:本节精读 quant-wiki docs/repo/static/strategies 下三个「统计套利」族系的脚本: (22 国 ETF 配对,120 日形成期 + 20 日交易期,价差偏离 0.5 倍标准差时开仓)、 (股债配对,季度比较两资产收益,买入赢家持有 1 季度)。前者是经典的 Gatev、Goetzmann、Rouwenhorst(2006)距离法配对,后者则是「配对」的极简版——只比较两个资产的相对强弱做轮动。本节讲清协整与距离两类配对选择的差异、价差均值回归的开平仓阈值、以及「形成期 vs 交易期」的两阶段时间结构,让你能看懂统计套利的工程骨架。
本节摘要:本节精读 quant-wiki docs/repo/static/strategies 下三个「统计套利」族系的脚本:
pairs-trading-with-country-etfs.py(22 国 ETF 配对,120 日形成期 + 20 日交易期,价差偏离 0.5 倍标准差时开仓)、paired-switching.py(股债配对,季度比较两资产收益,买入赢家持有 1 季度)。前者是经典的 Gatev、Goetzmann、Rouwenhorst(2006)距离法配对,后者则是「配对」的极简版——只比较两个资产的相对强弱做轮动。本节讲清协整与距离两类配对选择的差异、价差均值回归的开平仓阈值、以及「形成期 vs 交易期」的两阶段时间结构,让你能看懂统计套利的工程骨架。
内容来源:quant-wiki docs/repo/static/strategies,真实 Python 策略脚本,知识结构化整理。
⚠️ 学习提示:配对交易的核心假设是「价差均值回归」,但「历史协整不代表未来协整」。配对关系会因基本面变化(并购、行业转型、政策)而断裂,这种「配对崩溃」是统计套利最大的尾部风险。
阅读完本节,你应当能够:
统计套利(statistical arbitrage)是一大类策略的统称,核心是「找到历史稳定的价差关系,赌它会均值回归」。配对交易是其最经典的形态:
💡 关键区分:「相关」是两个资产收益同步涨跌,「协整」是两个资产价格的差距长期稳定。配对交易要的是协整(价差平稳),不是相关(可能共同下跌)。
pairs-trading-with-country-etfs.py 的整个生命周期分两个阶段:
| 阶段 | 长度 | 作用 |
|---|---|---|
| 形成期 | 120 个交易日 | 计算 22 个 ETF 之间所有配对的「距离」,选出 top-5 最近的 |
| 交易期 | 20 个交易日 | 对这 5 个配对监控价差,偏离阈值就开仓 |
每 20 天循环一次:重新形成期选配对 → 新交易期监控。脚本里用 self.days == 20 作为周期切换的触发:
self.period = 120 self.max_traded_pairs = 5 self.days = 20 # ... if self.days == 20: distances = {} for pair in self.symbol_pairs: distances[pair] = self.Distance(...) self.sorted_pairs = sorted(distances.items(), key=lambda x: x[1])[:self.max_traded_pairs] self.days = 0 self.days += 1
距离法(Gatev 等 2006)用「归一化价格序列的平方差之和」衡量两个 ETF 的「贴近程度」:
def Distance(self, price_a, price_b): norm_a = np.array(price_a) / price_a[-1] # 以最旧价格为基准归一化 norm_b = np.array(price_b) / price_b[-1] return sum((norm_a - norm_b)**2)
直觉:把两个 ETF 在形成期起点都归一化为 1,然后看它们在 120 天里的「轨迹差异」。SSD 越小,说明两者价格走势越贴近,越适合做配对(价差越可能均值回归)。
选好 5 个配对后,交易期每天监控其归一化价差:
norm_a = np.array(price_a) / price_a[-1] norm_b = np.array(price_b) / price_b[-1] spread = norm_a - norm_b mean = np.mean(spread) std = np.std(spread) actual_spread = spread[0] # 最新价差 # 开仓: 价差偏离 0.5 倍标准差 if actual_spread > mean + 0.5*std or actual_spread < mean - 0.5*std: # 开仓 多低估 / 空高估 # 平仓: 价差回归到均值附近 else: if pair in self.traded_pairs: # 反向平仓
阈值 0.5σ 偏小,意味着开仓频繁、单笔利润薄,靠量取胜。脚本对每个配对按「组合总价值的 1/5」分配资金,最多同时持 5 个配对。
⚠️ 陷阱:形成期与交易期的长度(120/20)是经验参数,直接影响策略表现。形成期太短,选出的配对不稳定;太长,可能错过市场结构性变化。交易期太长,配对可能已经失效。复现时这两个参数要做网格搜索。
脚本对每个持仓配对,要么「价差收敛到均值」平仓,要么「20 天交易期结束」强制平仓——后者是兜底机制,防止价差长期不回归导致死仓。这是统计套利的标准风控:不追求每笔都赚,但要控制单笔最大持有时间。
paired-switching.py 名字里也有「pair」,但逻辑完全不同。它不是「多空对冲赌均值回归」,而是「股债两资产里选强者」:
# 比较两资产过去 90 天的收益 first_performance = (Price_now_1 - last_p1) / Price_now_1 second_performance = (Price_now_2 - last_p2) / Price_now_2 # 买入赢家 if first_performance > second_performance: self.SetHoldings(self.first_symbol, 1) else: self.SetHoldings(self.second_symbol, 1)
股债配对切换依赖股债之间的负相关(风险偏好切换)。在风险偏好上升期,股票跑赢债券,策略持有股票;在风险偏好下降期,债券跑赢股票,策略持有债券。本质是一个「二选一的动量轮动」,而非对冲套利。
💡 对照:配对交易是「同时多空两个资产,赌价差回归」;配对切换是「二选一持有,赌趋势延续」。两者方向相反(一个均值回归,一个动量),只是都用了「pair」这个词。
ETF 配对脚本用的是距离法(SSD),但学术界更推崇协整法(Engle-Granger 或 Johansen 检验)。两者差异:
| 维度 | 距离法(SSD) | 协整法 |
|---|---|---|
| 指标 | 归一化价格的平方差之和 | 回归残差的平稳性 |
| 计算量 | 低(直接套公式) | 高(需做 ADF/EG 检验) |
| 鲁棒性 | 易受异常值影响 | 统计上更严格 |
| 工程友好 | 高(无需 statsmodels) | 中(依赖统计库) |
| 实务偏好 | 工业界(简洁) | 学术界(严谨) |
⚠️ 陷阱:距离法选出的配对可能「看似贴近但价差不平稳」(比如两者同步上涨但价差发散)。协整法更严格,但检验本身在小样本下功效低。两种方法都不是银弹,实务中常结合「先距离法粗选 → 再协整法精选」的两段式流程。
下一节,我们看风险溢价族系:低波动因子、波动率风险溢价(卖方差)、隔夜异常、残差动量。