3. 距离法策略:最小化平方距离法、标准化价格序列、固定阈值开平仓规则
距离法,说白了就是配对交易里最朴素、最直观的一种思路。你想想看,两只股票长期走势差不多,那它们之间的价差就应该在一个合理范围内晃悠。一旦价差跑偏了,那就是机会——赌它迟早会回归。
我个人最早接触配对交易,就是从距离法入手的。那时候还没那么多花里胡哨的机器学习模型,大家就靠算距离、设阈值来赚钱。嗯,今天咱们就把这套经典玩法彻底讲透。
3.1 核心思想:价差回归
距离法的逻辑其实特别简单:
- 找到两只相关性高的股票
- 计算它们的价差(或价差的某种变形)
- 价差偏离到一定程度就开仓,回归了就平仓
关键问题来了:怎么定义「价差」?怎么定义「偏离」?
我在项目中遇到过不少新手,上来就用原始价格算价差。结果呢?茅台和五粮液价格差了几百块,这能直接比吗?显然不行。所以我们需要对价格做标准化处理。
3.2 标准化价格序列
标准化的目的,就是把不同量级的股票价格拉到同一个尺度上。常用的方法有两种:
方法一:Z-Score 标准化
把价格序列减去均值,再除以标准差。公式很简单:
z = (price - mean(price)) / std(price)
这样处理后,两只股票的价格都变成了均值为0、标准差为1的序列。它们之间的差值,就是标准化的价差。
方法二:Min-Max 标准化
把价格压缩到 [0, 1] 区间:
norm_price = (price - min(price)) / (max(price) - min(price))
我个人习惯用 Z-Score,因为它保留了价格波动的统计特性,方便后面设阈值。
3.3 最小化平方距离法
标准化之后,我们怎么衡量两只股票的「距离」?最经典的做法就是最小化平方距离。
具体来说,我们假设两只股票的价格存在一个线性关系:
P_A = β * P_B + ε
其中 β 是 hedge ratio(对冲比率),ε 是残差(也就是价差)。
最小化平方距离,就是找到那个 β,让残差的平方和最小。说白了,就是做一次线性回归:
import numpy as np
def calculate_hedge_ratio(price_a, price_b):
# 最小二乘法求对冲比率
cov_matrix = np.cov(price_a, price_b)
beta = cov_matrix[0, 1] / cov_matrix[1, 1]
return beta
# 计算价差
beta = calculate_hedge_ratio(price_a, price_b)
spread = price_a - beta * price_b
这里有个坑,我曾经踩过:直接用原始价格回归,β 会随着时间漂移。所以我建议用滚动窗口来估计 β,比如每20个交易日重新算一次。
3.4 固定阈值开平仓规则
有了标准化的价差序列,接下来就是定规则了。固定阈值法是最简单粗暴的:
| 价差状态 | 操作 | 阈值条件 |
|---|---|---|
| 价差过大(正向) | 做空价差:卖A买B | spread > +2σ |
| 价差过小(负向) | 做多价差:买A卖B | spread < -2σ |
| 价差回归 | 平仓 | |spread| < 0.5σ |
| 止损 | 强制平仓 | |spread| > 3σ |
这里的 σ 是价差序列的标准差。2σ 和 0.5σ 是经验值,你可以根据回测结果调整。
3.5 完整策略流程
把上面这些串起来,一个完整的距离法策略长这样:
def distance_strategy(prices_a, prices_b, window=60, entry_z=2, exit_z=0.5):
# 1. 滚动标准化
z_a = rolling_zscore(prices_a, window)
z_b = rolling_zscore(prices_b, window)
# 2. 滚动计算对冲比率
beta = rolling_beta(prices_a, prices_b, window)
# 3. 计算标准化价差
spread = z_a - beta * z_b
# 4. 生成信号
signals = []
position = 0 # 0:空仓, 1:多头, -1:空头
for i in range(len(spread)):
if position == 0:
if spread[i] > entry_z:
signals.append(-1) # 做空价差
position = -1
elif spread[i] < -entry_z:
signals.append(1) # 做多价差
position = 1
else:
signals.append(0)
else:
if abs(spread[i]) < exit_z:
signals.append(0) # 平仓
position = 0
else:
signals.append(position)
return signals
3.6 知识体系总览
下面这张图,把距离法策略的核心逻辑串起来了:
3.7 避坑指南
距离法看着简单,但坑不少。我把自己踩过的坑列出来,你注意避开:
- 不要用全量数据标准化——这会导致未来信息泄露,回测漂亮,实盘拉胯
- β值要滚动更新——股票的相关性会变,固定β会让你亏到怀疑人生
- 阈值要动态调整——市场波动率在变,固定阈值等于刻舟求剑
- 注意交易成本——配对交易频繁开平仓,手续费和滑点能吃掉你大部分利润
核心要点:距离法策略的精髓不在于「距离怎么算」,而在于「什么时候算、用什么窗口算」。滚动窗口的大小、更新频率、阈值参数,这些才是决定策略生死的关键。我建议你从60天窗口、2σ开仓、0.5σ平仓开始调参,然后逐步优化。
好了,距离法就讲到这里。这套方法虽然老,但它是理解配对交易的基石。后面更复杂的协整法、机器学习法,本质上都是在距离法的基础上做改进。把今天的内容吃透,后面的路就好走了。