前言
在量化交易的所有策略流派里,均值回归可能是最"反直觉"的一个。
为什么这么说?因为大部分新手接触交易的第一反应都是"追涨杀跌"------看到涨了就想买,觉得它会继续涨。这是人类的本能,也是动量策略的心理基础。但均值回归告诉你:恰恰相反,涨多了该卖,跌多了该买。价格偏离越远,回来的概率越大。
听起来很"常识"------毕竟"物极必反""否极泰来"是老祖宗几千年前就总结的智慧。但常识归常识,当你面对一个已经连跌7天的品种,你敢不敢逆势买入?当一个品种连续创新高,你敢不敢做空?大部分人做不到,因为你的本能会告诉你"它还会涨"或者"它还会跌"。
均值回归策略的价值,就在于用数学和数据替你克服这个本能偏差。它不需要你"判断"价格是否"跌多了",而是用统计检验告诉你:当前偏离是否已经超过了历史均值的一定倍数,回归的概率有多大,预期的回归周期是多长。
这篇文章,我会从均值回归的底层逻辑讲起,到它的数学基础、实操步骤、风控要点,帮你完整搭建一套可落地的均值回归策略框架。

Why:为什么均值回归是投资世界最古老的信仰?
两次黑色星期一
1987年10月19日,星期一。道琼斯工业平均指数在一天之内暴跌了22.6%。这不是小幅回调,是人类现代金融史上最剧烈的单日崩盘之一。全球恐慌蔓延,所有分析师都在说同一句话:"这次不一样",资本主义要完了。
然后呢?
12个月后,美股反弹了23%,完全收复了跌幅。
2008年10月,雷曼兄弟破产后的余波。标普500从高点一路跌去40%,有人甚至在电视上喊"卖出一切"。但到了2009年3月,市场见底,然后用10年时间涨了4倍。
这两次事件完美展示了同一个规律:价格可以短期极端偏离均衡,但最终一定会回来。 不是"可能"回来,是"几乎必然"回来。
这不是鸡汤。这是统计学。
从股票到商品:均值回归无处不在
均值回归不是某个市场的特例。从美股到A股,从黄金到原油,从外汇到债券,只要价格是由供需基本面决定的,偏离越大回归的概率就越高。
原因很简单:价格偏离均衡意味着经济激励的扭曲。油价涨到200美元,页岩油商就会疯狂增产,需求端会因为高油价而萎缩,供给增加+需求减少,价格自然回落。股价跌到远低于净资产,公司就会回购,价值投资者就会买入,买盘增加,价格自然反弹。
均值回归的底层驱动力是经济系统的自我修正机制。 当价格偏离到足够极端,"便宜"本身就会成为上涨的理由,"昂贵"本身就会成为下跌的理由。
均值回归 vs 动量:一枚硬币的两面
上一节讲了动量策略------过去的赢家继续赢、过去的输家继续输。均值回归刚好相反------过去的赢家会"降温"、过去的输家会"反弹"。
两种策略都有效,但有效的时间尺度不同:
• 短期(日、周) :均值回归占优。因为信息消化后价格会回归合理区间,短期超涨超跌会被修正。
• 中期(月、季) :动量占优。因为信息需要时间扩散,趋势需要时间形成。
同一个品种,短期做均值回归、中期做动量,两个策略可以同时有效。关键是你用哪个时间尺度。
What:均值回归的数学基础
OU过程:均值回归的数学语言
均值回归策略需要一个精确的数学模型来描述"价格如何回归均值"。最经典的模型是Ornstein-Uhlenbeck过程 (简称OU过程),这是金融数学中描述均值回归行为的标准工具。
数学表达:
dX(t) = θ × (μ - X(t)) × dt + σ × dW(t)
拆解每个符号:
• X(t):当前价格(或者价差、偏离度)
• μ:长期均值(均衡价格)
• θ:回归速度参数。这是最重要的参数。 θ越大,偏离后回归越快;θ=0,价格变成随机游走,完全没有回归趋势
• σ:波动率,描述价格随机波动的幅度
• dW(t):布朗运动的增量,代表随机扰动
简单翻译成人话:价格每一天的变动 = 回归力量(把价格拉向均值)+ 随机扰动(市场噪音)。θ决定了回归力量的大小。
半衰期:你该持仓多久?
OU过程中有一个极其重要的衍生指标:半衰期 (Half-Life)。
半衰期 = ln(2) / θ
意思是:如果当前价格偏离均值一定距离,经过多长时间后,偏离会缩小到原来的一半。
半衰期的实战意义极其重大:
• 如果半衰期是5天:你的均值回归策略持仓周期应该在5天左右。偏离后5天,价格大概率回归到一半。持仓超过5天,边际收益递减。
• 如果半衰期是60天:你的策略应该以月为周期持仓。不要指望几天就回归。
• 如果半衰期是200天以上:这个品种基本没有均值回归特征,不要做。
持仓周期和半衰期不匹配,是均值回归策略亏损最常见的原因。 很多人选了半衰期30天的品种,然后用5天的持仓周期------还没回归就平仓了,当然赚不到钱。反过来也是,半衰期5天的品种你持仓30天,早就回归完了,后面的持仓纯粹是在承担随机波动风险。
如何从数据中估计θ和半衰期?
实操中,我们用AR(1)回归来估计回归速度:
// python
import numpy as np
import pandas as pd
import statsmodels.api as sm
from statsmodels.tsa.stattools import adfuller
def estimate_mean_reversion(prices):
"""
从价格序列中估计均值回归参数
返回:
- is_stationary: ADF检验是否通过(p<0.05)
- half_life: 半衰期(天数)
- b: AR(1)系数
- theta: 回归速度
"""
第一步:ADF检验------判断是否存在均值回归
adf_result = adfuller(prices, maxlag=1)
adf_p_value = adf_result1
is_stationary = adf_p_value < 0.05
第二步:AR(1)回归
X(t) = a + b × X(t-1) + ε
y = prices.iloc1:
x = prices.iloc:-1
x_const = sm.add_constant(x)
model = sm.OLS(y, x_const).fit()
b = model.params.iloc1
第三步:计算半衰期和回归速度
if 0 < b < 1:
half_life = -np.log(2) / np.log(b)
theta = -np.log(b)
else:
half_life = np.nan
theta = np.nan
return is_stationary, half_life, b, theta
逐行解释:
• adfuller(prices):Augmented Dickey-Fuller检验。原假设是"序列有单位根"(随机游走)。p值<0.05意味着拒绝原假设,序列是平稳的(存在均值回归)
• sm.OLS(y, x_const).fit():普通最小二乘回归,估计AR(1)系数b
• b接近1:几乎随机游走,回归极慢(动量世界)
• b在0.85-0.99之间:典型均值回归品种
• b为负:过度回归,价格在均值两侧反复震荡
• half_life = -np.log(2) / np.log(b):从AR(1)系数反推半衰期
均值回归的三种经典场景
场景一:单资产均值回归
最直观的形式:一只股票的价格偏离自身均线后回归。比如乖离率(BIAS)策略------当价格跌破20日均线15%时买入,回归到均线时卖出。
适用对象:大盘蓝筹、指数ETF、高流动性品种。这些品种的"均值"相对稳定,不太容易出现均值漂移。
场景二:配对均值回归
两个相关资产的价差围绕均值波动。比如可口可乐和百事可乐的股价差,或者同一公司在A股和H股之间的价差。价差偏离均值时做多被低估的、做空被高估的。
适用对象:同行业龙头配对、同一资产的不同市场报价。配对的协整关系越强,均值回归越稳定。
场景三:因子均值回归
风格因子(如价值溢价、小盘溢价)的周期性波动。比如价值因子在某个阶段失效了(成长跑赢价值),但长期来看价值因子会回归。
适用对象:多因子策略中的因子择时。当某个因子偏离历史均值2个标准差以上时,增加该因子暴露。
均值回归 vs 动量:适用环境对比
|----------|-----------------|---------------|
| 环境特征 | 均值回归占优 | 动量占优 |
| 市场状态 | 震荡市、区间波动 | 趋势市、单边行情 |
| 信息消化速度 | 信息快速消化、价格快速修正 | 信息缓慢扩散、趋势逐步建立 |
| 参与者结构 | 套利者主导(成熟市场) | 正反馈交易者主导(散户多) |
| 时间尺度 | 短期(日、周) | 中期(月、季) |
| 典型品种 | 配对价差、利差、均值回复型商品 | 趋势型商品、成长股 |
| 收益特征 | 高胜率、低盈亏比 | 低胜率、高盈亏比 |
How:均值回归策略的落地步骤
第一步:选品------找出真正有均值回归特征的品种
不是所有品种都适合均值回归。很多品种看起来"跌多了会涨",但统计检验后发现根本不存在稳定的均值回归特征。
选品三标准:
-
ADF检验p值 < 0.05(统计上确认存在均值回归)
-
半衰期在5-60天之间(太短被交易成本吃掉利润,太长资金效率低)
-
AR(1)系数b在0.85-0.99之间(太低意味着过度震荡,太高意味着回归太慢)
// python
def screen_mean_reversion_candidates(price_dict):
"""
批量筛选均值回归品种
参数:
- price_dict: {品种代码: 收盘价Series} 的字典
返回:
- 符合条件的品种列表,按半衰期排序
"""
results = \[\]
for code, prices in price_dict.items():
is_stationary, half_life, b, theta = estimate_mean_reversion(prices)
三个条件全部满足
if is_stationary and 5 <= half_life <= 60 and 0.85 <= b <= 0.99:
results.append({
'code': code,
'half_life': round(half_life, 1),
'b': round(b, 4),
'theta': round(theta, 4)
})
按半衰期排序(短半衰期优先)
results.sort(key=lambda x: x'half_life')
return pd.DataFrame(results)
第二步:确定均值和偏离度
"均值"的选择比想象中更讲究。不同的均值算法,策略表现差异很大。
三种均值算法:
-
简单移动均值(SMA) :过去N天收盘价的算术平均。最简单,但滞后严重。适合均值本身非常稳定的品种。
-
指数加权均值(EWMA) :对近期数据赋予更高权重。对均值漂移更敏感,适合"均值本身也在缓慢变化"的品种。
-
Kalman滤波均值 :用状态空间模型实时估计动态均值。最灵活,但实现复杂,过拟合风险高。建议高级用户在单资产策略验证有效后再考虑。
偏离度度量------Z-score:
Z-score = (当前价格 - 均值) / 标准差
Z-score = 2,意味着当前价格偏离均值2个标准差。在正态分布假设下,Z > 2的概率只有2.3%,属于极端偏离。
第三步:设计入场和出场规则
经典Z-score阈值设计:
|--------|----------------|--------------|
| 操作 | Z-score阈值 | 逻辑 |
| 开多 | Z < -2 | 价格严重偏低,买入等回归 |
| 开空 | Z > +2 | 价格严重偏高,做空等回归 |
| 平多 | Z > -0.5 | 回归到均值附近,止盈 |
| 平空 | Z < +0.5 | 回归到均值附近,止盈 |
| 止损 | 亏损超过入场时偏离的1.5倍 | 均值可能已经漂移 |
止损为什么极其重要?
均值回归策略最大的风险不是"均值不存在",而是均值漂移 ------你以为的"均值"已经变了。价格偏离的不是旧均值,而是围绕新均值波动。不设止损,就是在赌均值不变,这在现实中极其危险。
经典案例:2008年金融危机前,很多人做空金融股,理由是"股价偏离历史均值太远了,一定会回归"。结果金融股的均值永久下移了,那些做空的人等到的是破产而不是回归。
第四步:仓位管理
// python
def mean_reversion_position(z_score, half_life, max_position=1.0):
"""
均值回归仓位管理
核心逻辑:
- 仓位大小与偏离度成正比------偏离越大,仓位越重
- 半衰期越长,仓位越保守------回归慢,不要急
"""
基础仓位:偏离度越大仓位越重
z=-2时做多满仓,z=+2时做空满仓
raw_position = -z_score / 2.0
半衰期修正:长周期品种减仓
if half_life > 30:
raw_position *= 0.5
elif half_life > 15:
raw_position *= 0.75
限制最大仓位
position = max(-max_position, min(max_position, raw_position))
return position
第五步:回测验证
回测数据仅作教学演示,不代表未来表现
回测要点:
• 用ADF检验预筛选品种,不要对所有品种做均值回归
• 按半衰期分组:短半衰期(5-15天)和长半衰期(15-60天)分别回测
• 必须包含交易成本(手续费+滑点)
• 必须设置止损(偏离超过3倍标准差无条件出场)
典型回测结果参考:
• 纯Z-score策略(Z=±2入场,Z=0平仓):年化约4-6%,胜率约60%
• 叠加半衰期匹配后:年化提升到6-8%,最大回撤从-25%降到-15%
• 多品种分散后(10+品种):夏普比率1.0-1.5
第六步:风控铁律
-
必须设止损 :偏离超过3倍标准差无条件止损,不要扛单等回归
-
不要在强趋势品种上做均值回归 :先用ADF检验过滤掉趋势品种
-
多品种分散 :单一均值回归头寸风险极高,至少10个品种组合
-
定期重估参数 :均值和半衰期不是固定不变的,建议每季度重新估计
-
区分"均值回归"和"接飞刀" :真正的均值回归有统计检验支撑,接飞刀只是凭感觉抄底
总结
均值回归是最古老的投资直觉------"物极必反""否极泰来"。但从直觉到策略,中间隔着一道关键的分界线:你怎么确认"跌多了"而不是"趋势变了"?
答案是数学。用ADF检验确认品种是否存在均值回归特征,用半衰期确定合理的持仓周期,用Z-score量化偏离程度,用止损保护均值漂移的尾部风险。
均值回归和动量不是对立的,它们是同一枚硬币的两面。短期做均值回归、中期做动量,两者组合使用才是最完整的量化框架。
记住这句话:信仰需要数学来守护。 不是"跌多了就该涨",而是"跌到Z=-2且ADF检验通过且半衰期在合理范围内,做多才有统计优势"。