如果你做过一点量化交易,或者只是看过别人复盘,“均值回归”这四个字一定不陌生。我第一次真正把它用在策略里,是在一个明显超涨的标的出现长上影之后。当时逻辑很简单:价格已经偏离均线很多,情绪迟早要消散,于是逆势空单进去。结果连续三次止损,我才意识到自己根本没有搞清楚眼前这轮上涨是噪声,还是新的趋势起点。这个系列写到第四篇,前几篇我们一直在强调价格行为需要用概率视角去理解;今天要聊的均值回归,恰好是这套视角里最诱人、也最容易用错的一环。我的主判断很明确:均值回归不是一个“预测价格会回到哪里”的工具,而是一种关于极端值如何形成的概率框架。把它当作预测工具,你会不断被市场教育;把它当作风险管理工具,它才真正有复利价值。
1. 先搞清楚:均值回归到底在说什么
1.1 高个子父母的后代,为什么会“变矮”
均值回归最早被系统研究,通常要提到弗朗西斯·高尔顿的豌豆实验:高个子的父母,后代的平均身高往往比父母矮一些,更接近整个人群的平均值;矮个子的父母,后代平均身高又会比父母高一些。这个现象后来被称为回归均值(regression to the mean)。它给普通人的直觉判断是:极端值之后,更可能出现不那么极端的结果。
但这里很容易产生一个误解:好像有一种神秘的力量把一切都拉向平均水平。实际不是。高尔顿观察到的并不是因果机制,而是一个统计关系。在包含测量误差和随机波动的世界里,一个样本之所以表现得极端,往往有一部分原因是运气好或者运气差。等到下一次测量时,运气成分大概率不会重复,所以结果会“收敛”到更接近均值的位置。这不是命运,而是条件期望在起作用。
我们需要明确一点:回归到均值并不意味着“一定会回到同一个值”,而是说下一次观测的条件期望更接近整体均值。用数学一点的话讲,当你有 X 和 Y 两个相关变量时,Y 的期望值不会与 X 的极端值一样极端,而是会向它的均值收缩。这是双变量正态分布的自然属性。理解这一点,再看交易中的均值回归,就不会把它当成“保证会回到某条线”的咒语。
1.2 极端观测值是信号还是噪声
要把均值回归用到实盘,第一个问题不是“偏离了多少”,而是“这个极端值是否由可持续的信息驱动”。
假设一个品种平时每天波动在1%以内,某天突然上涨5%。表面看,5%明显偏离均值,均值回归策略会认为应该做空。但如果这一天的5%来自突发的基本面变化,比如行业政策调整、公司重大合同落地,那么价格中枢可能已经上移,原来的“均值”不再代表合理价值。此时做空并不是在交易均值回归,而是在逆着一次真正的趋势切换。
所以,任何均值回归策略在使用前,都必须先做一个拆解:当前价格 = 价值中枢 + 暂时性偏差 + 持续性新信息。均值回归策略能赚的是“暂时性偏差”被纠正的钱,一旦偏差背后混入了持续性信息,策略就会失效。这也是为什么很多人在趋势行情里用均值回归会连续亏损的原因:他们在均值已经移动的行情中,仍然用旧均值来判断偏离。
1.3 硬币并不会因为连续正面而变得反面更容易
很多人会把均值回归和“大数定律”混在一起。抛硬币连续10次正面,第十一次正面的概率还是50%。硬币没有记忆,它不会因为前面正面太多而主动增加反面的概率。但如果你统计“累计正面比例”,长期看这个比例会稳定在50%附近——这就是一种均值的吸引现象,但它的产生机制是独立随机过程的平均效应,而不是反馈机制。
在价格序列里也存在类似陷阱。比如一个品种过去20天上涨了30%,有人会认为“接下来回归的概率很大”。但如果上涨是由基本面持续改善驱动的,接下来继续上涨的概率仍然是高的。价格上涨本身并不会产生“必须下跌”的压力。均值回归交易能盈利的品种和时段,往往存在真正的负反馈机制:比如做市商的反向操作、套利者迅速平仓、短期流动性枯竭后的修复,这些机制会让偏离被拉回。
所以,在策略层面,你需要找到“为什么会出现负反馈”的证据,而不是只看到“价格偏离了均线”。这一点决定了均值回归策略是逻辑驱动,还是纯粹数据挖掘。
2. 交易里的均值回归:看着合理,为什么老亏钱
2.1 交易层面的均值回归,到底在假设什么
交易者常说的均值回归,是指价格在偏离一段时间后,会重新回到某个价值中枢附近。这个价值中枢可以是移动平均线、成交量加权均价、某条回归线,也可以是一篮子股票的相对价差。它背后真正依赖的假设有三个:
- 参照系是稳定的,不会在持仓期间快速漂移;
- 当前偏离主要来自暂时性情绪或流动性冲击,而不是永久性信息冲击;
- 回归速度足以覆盖交易成本和资金占用。
这三个假设听起来很温和,但在真实行情里经常被违反。尤其在A股或加密货币这类波动大的市场,政策、监管、资金结构变化都会让“中枢”发生跳变。换句话说,均值回归策略赚的并不是市场“有规律”的钱,而是在市场充分有效之前,利用某些短期失效获取的流动性补偿。
2.2 布林带、RSI、Z-score 和配对交易
常见的均值回归表达方式有这么几类,新手至少要知道它们各自的差异:
- 布林带:把移动平均线当均值,上下轨设置成若干倍标准差。价格触及下轨时做多,触及上轨时做空,回归中轨时平仓。它假设价格围绕移动平均上下波动,但移动平均本身会随趋势移动,所以布林带更适合震荡行情。
- RSI:相对强弱指数,衡量一段时间内上涨幅度占整体涨跌幅的比例。RSI高(比如大于70)被认为超买,低(小于30)被认为超卖。它本质是动量指标,但在均值回归策略中会被当作超买超卖信号,适合短周期反转。
- Z-score:当前价格与均值的差值除以标准差,得到一个标准化的偏离度。这个指标的优点是跨品种可比,缺点是需要自己定义均值和标准差的窗口。
- 配对交易:找两个历史上相关性较高的资产,当价差偏离长期均值时,做多低估方、做空高估方,等价差回归后平仓。它把均值回归从“单边赌价格”变成了“赌价差关系”,风险相对可控,但仍要面对关系瓦解的风险。
这些工具没有绝对优劣,关键是你要清楚自己交易的是哪种“均值”。如果均值定义错了,后面的止损、仓位、加仓就全都会错。
2.3 三个容易触发亏损的前提破坏
第一,均值漂移。这是最常见的问题。你用过去60日均线做均值,但如果企业盈利中枢在上移,旧均值已经失去了参照意义。此时信号会不断给出反向入场,然后不断被趋势打穿。
第二,偏离持续扩大。均值回归策略天然需要“负反馈”,但市场短期可能继续正反馈。如果没有严格的止损,一次极端行情就可以吃掉此前几十次盈利。因为这本质上是“接飞刀”,你永远不知道刀还有多长。
第三,交易成本吞噬。均值回归策略通常交易频率较高,因为每次偏离到阈值就入场,回落到均值附近就出场。如果手续费、冲击成本、滑点过高,很多看起来盈利的回测实际上长期亏损。尤其在流动性较差的品种上,这个损耗会被放大。
这三个破坏点决定了均值回归不是“放着不管就能赚钱”的策略,而是需要持续监控均值是否有效、市场是否为震荡环境、成本是否可控。
3. 把均值回归变成策略前,先回答三个变量
3.1 均值:你的“价值中枢”到底用多长时间
选择均值窗口,是最开始就要做的事。窗口太短,均值跟随价格快速移动,偏离被压缩,信号变少;窗口太长,均值对新的信息反应迟钝,偏离看起来很大,但回归可能永远不会发生。常见做法是先用品种的波动周期做参考,比如日内交易用15分钟到1小时均线,波段交易用20日到60日均线,长线可能要考虑周线级别。
这里没有万能参数。更值得参考的是:你交易的品种,过去一段时间的价格波动是否有一个相对稳定的中枢?如果没有——比如长期单边上涨——那么任何窗口的均值都只是“一条跟着趋势走的上行线”,偏离信号会被趋势不断覆盖。从工程经验看,先画几根不同窗口的移动平均,再叠加最近的K线走势,比直接调参更直观。
3.2 偏离:用标准Z-score而不是百分比
判断偏离程度时,我最建议用Z-score而不是固定百分比。因为不同品种的波动率差异极大,2%对黄金可能已经很大,对某些加密货币可能只是平均水平。Z-score = (当前价格 - 均值) / 标准差,可以将波动率归一化,让偏离程度跨品种可比。
具体实现时,需要计算滚动窗口的标准差,并且注意是否使用总体标准差。在常见Python代码里,pandas 的 rolling std 默认 ddof=1,也就是样本标准差。如果计算股票日线,样本标准差和总体标准差差异不大,但会影响阈值;最好统一说明,并在回测中保持一致。
阈值的选择也不是越大越好。阈值2.0意味着假设偏离服从正态分布,尾部概率大约2.28%,但价格收益并不严格正态,尾部更厚。所以很多策略会把阈值设为1.5或者2.5,取决于品种和风险偏好。与其套固定值,不如看过去一年Z-score的分位数:选80%分位以上作为入场,20%以下作为另一方向入场,这样阈值就会自适应数据分布。
3.3 回归时间:没有时间约束的交易是伪命题
很多人设计均值回归策略时,只关心入场信号和出场信号:偏离到阈值就进,回到0就出。但现实里,价格可能偏离很久,资金占用成本会累积,持仓过程也可能不断触及止损。
所以必须在策略里加入时间约束。常见做法有两种:最大持仓天数/周期数,超过即平仓,不管是否回归到均值;或者设置一个“回归时间预期”,比如统计历史上偏离到这个程度后,平均需要多少个周期才回归,只保留在预期时间内未回归就强制离场的逻辑。
加入时间约束的本质,是提醒自己:均值回归不是一个无成本等待的过程。你的资金是有限的,市场也可能连续偏离很多天,时间约束能防止你为了一个统计期望,把账户变成长期套牢。
3.4 一个最小可运行的Z-score骨架
下面给一个示意代码结构,用来理解核心流程,不代表可以直接用于实盘,也不构成任何投资建议。
import pandas as pd import numpy as np def zscore_signal(price, window=20, entry=2.0, exit_threshold=0.0, max_hold=10): df = pd.DataFrame({'price': price}) df['ma'] = df['price'].rolling(window).mean() df['std'] = df['price'].rolling(window).std(ddof=0) df['zscore'] = (df['price'] - df['ma']) / df['std'] position = 0 entry_bar = 0 for i in range(len(df)): if pd.isna(df['zscore'].iloc[i]): continue if position == 0: # 做空条件:zscore 上穿 entry if df['zscore'].iloc[i] > entry: position = -1 entry_bar = i # 做多条件:zscore 下穿 -entry elif df['zscore'].iloc[i] < -entry: position = 1 entry_bar = i if position != 0: # 平仓条件:zscore 回到 exit_threshold 附近,或超出最大持仓 if abs(df['zscore'].iloc[i]) < abs(exit_threshold) or (i - entry_bar) >= max_hold: position = 0 return df注意几个细节:代码里用了ddof=0,表示总体标准差,方便阈值解释;max_hold是时间约束;入场在当根K线收盘后确认,实际执行最好放在下一根K线开盘,避免未来函数。具体优化方向包括动态均值窗口、阈值分位数化、加入波动率过滤、加入趋势过滤(比如只在均线走平时使用)。
注意:上面的代码只是一个理解流程的骨架,没有处理停牌、涨跌停、手续费、滑点和未来函数。真正落地前,把它接到自己的回测框架里,先做样本外测试。
4. 回测会骗人:这套策略最容易被误用的地方
4.1 回测好看的五个常见原因
第一,未来函数。最常见的是在计算指标时使用了未来的数据。比如你想在收盘时根据当天收盘价计算Z-score,然后在同一根K线的最高价或最低价成交,这等于你提前知道了全天最低点,回测结果自然漂亮。正确做法是:当天收盘确认信号,次日开盘执行。
第二,幸存者偏差。回测时只选择了现在还在市场上的品种,退市、停牌的都被剔除了。这会让策略看起来一直能盈利,因为那些让你亏到退市的都不在你的样本里。要避免,需要在回测时使用全量标的池,并考虑退市机制。
第三,参数过拟合。不断调整窗口和阈值,直到历史曲线完美。这种策略往往在样本外很快失效。判断方法很简单:把参数变化做成热力图,如果盈利只集中在几个孤立的“尖峰”,说明是过拟合;如果大片区域都能盈利,才算相对稳健。
第四,忽略成本。均值回归策略交易频率高,每次偏离入场和回归出场都产生手续费和滑点。回测如果不加成本,看到的是“理论收益”,实际可能被成本吃掉一截。
第五,没有止损。很多均值回归策略假设价格一定会回归,所以不设止损。一旦遇到单边趋势,亏损可以无限扩大。回测里可能偶尔一次巨亏就毁掉长期收益,但由于你不看最大回撤,很难发现。
4.2 一个可复用的策略排查链路
如果你自己写了一套均值回归策略,回测结果看起来不错,我建议按下面顺序排查一遍:
- 数据清洗:确认没有缺失值、没有前复权导致的跳变、没有把退市股混进标的池。
- 信号与执行时序:在回测引擎里检查信号生成是在 bar 收盘后还是盘中;成交价是否使用了未来信息。
- 成本模型:先给手续费和滑点加上保守估计,再看净收益是否为正。
- 参数稳定性:固定种子或随机做一段样本内优化,重点看参数热力图是否平滑。
- 样本外验证:把数据按时间切分,前半段调参,后半段测试,避免用全局信息做特征。
- 极端行情压力测试:加入单日暴涨暴跌、连续下跌、停牌复牌等场景,观察最大回撤。
这套排查顺序不只适用于均值回归,几乎所有量化策略落地前都可以先用它过一遍。它不能保证策略赚钱,但能避免一部分“回测看起来很爽、实盘直接崩溃”的坑。
排查一个策略是否可靠,先别急着优化参数,而是检查数据流向是否作弊。方向错了,参数越优化越危险。
4.3 均值回归策略适合谁、不适合谁
适合这样的环境:市场处于震荡、缺乏单边趋势、波动主要由情绪驱动、品种流动性较好、交易成本可控。典型场景是外汇盘整、期货品种无重大基本面变化、股票指数短期超跌反弹等。
不适合这样的环境:强趋势行情(比如突破后持续上涨)、基本面发生重大变化、政策冲击、小品种流动性差、交易成本过高。在这些场景里,趋势跟踪策略更合理,均值回归往往会成为反向指标。
用一张表总结:
| 场景 | 更适用的策略逻辑 | 均值回归风险 |
|---|---|---|
| 震荡市 | 高抛低吸,回归中枢 | 较低,但要防均值漂移 |
| 强趋势市 | 顺势持仓 | 高,容易逆势接飞刀 |
| 基本面突变 | 快速反应新信息 | 很高,旧均值失效 |
| 低流动性品种 | 等市场修复后再参与 | 很高,成本与滑点放大 |
| 高频/日内短周期 | 微观结构回归 | 中等,依赖执行速度 |
这张表解决的是“什么时候不要用”的问题。大部分均值回归亏损,不是策略本身错了,而是用错了环境。
5. 均值回归的通用认知价值
5.1 从数据波动中分辨噪声和信息
均值回归不只是交易概念,它本质上是一种数据理性。拿内容创作举例:一篇图文突然爆了,如果第二天数据回落到日常水平,并不代表你的内容质量骤降,而是上次爆款里有大量随机流量;一次投放转化率突然很高,也可能只是小样本下的偶然。你要做的是判断这次偏离是新能力的信号,还是随机波动。如果连续多天偏离,才值得重视。
这和统计里的“控制图”思路很像:先设定一个基准均值,再画上下控制线。点落在控制线内,就认为是正常波动;连续多个点落在同一侧,才认为均值可能发生了变化。均值回归思维并不是要你对所有极端都无动于衷,而是提醒你:先分清楚这是信号还是噪声,再决定是否行动。
5.2 “三问”判断框架
遇到任何极端数据,我都会先问自己三个问题:
- 这个偏离是噪声还是信息?判断依据是:是否有可解释的逻辑,比如业务逻辑、基本面变化、运行故障,而不仅仅是数字奇怪。
- 如果回归,回归的对象是哪个均值?这个均值本身会不会动?如果业务目标在增长,用历史均值做锚就错了。
- 如果要等待回归,需要多少时间和成本?如果等待时间太久,中间发生的新变化可能已经改变均值,原来的回归策略就不再有意义。
这三个问题可以快速套用到运营指标、产品功能、个人学习反馈等场景。它不能直接告诉你答案,但能避免你在一次随机波动里做出过度反应,也不会让你错过真正的趋势变化。
举个例子:某个功能上线后,次日活跃用户突然涨了20%,你第一反应可能是功能很成功。但如果再把之后三天数据拉出来,发现已经回落到只比旧均值高2%,那次20%更可能是上线初始曝光、应用商店推荐等一次性因素带来的噪声。真正的功能价值需要更长时间窗口来判断,而不是用单日极值下结论。
5.3 不适用均值回归的典型场景
均值回归最怕的是“没有稳定均值”的场景。比如一个快速成长产品的日活跃用户,持续上升,你用过去30天均值去判断短线回落,会发现永远有偏。因为均值本身在向上移动,你必须用包含趋势的模型去拟合,而不是简单求平均值。同理,当一个行业的商业模式正在重塑,历史估值中枢会失效,均值回归策略在这里没有锚。
所以不要把所有均值回归都等同于“跌多了会涨”。它只在均值相对稳定、偏离由暂时性因素驱动、且存在负反馈机制时有效。脱离这些条件,它只是一个统计幻觉。真正的策略不是永远押注回归,而是不断检验当前市场是否还满足回归的前提;一旦发现均值在漂移、反馈机制在消失,就应该迅速切换到趋势策略或者直接空仓等待。这一点,才是均值回归从理论变成工具的关键。
回到一开始我连续三次止损的经历。我现在仍然使用均值回归相关的策略,但心态完全不同。我不会再因为它“偏离了均值”就认定价格一定回归,而是先问自己:均值还在不在?偏离背后的信息是临时的还是永久的?如果等待太久,我还拿不拿得住?这些问题没有标准答案,却能拦下大部分冲动交易。均值回归真正的价值,不是让我们在极端点位上精准抄底摸顶,而是让我们理解:极端值并不等于规律,信号需要证据,等待需要成本。当你把它从一个“预测工具”降级成“风险管理框架”,你会发现自己少了很多不必要的操作,也少走了很多弯路。