
用 Python 揭秘均值回归策略:你的收益从何而来?
2026年重磅升级已全面落地!欢迎加入专注财经数据与量化投研的【数据科学实战】知识星球!您将获取持续更新的《财经数据宝典》与《量化投研宝典》,双典协同提供系统化指引;星球内含 350 篇以上独有高质量文章,深度覆盖策略开发、因子分析、风险管理等核心领域,内容基本每日更新;同步推出的「量化因子专题教程」系列(含完整可运行代码与实战案例),系统详解因子构建、回测与优化全流程,并实现日更迭代。我们持续扩充独家内容资源,全方位赋能您的投研效率与专业成长。无论您是量化新手还是资深研究者,这里都是助您少走弯路、事半功倍的理想伙伴,携手共探数据驱动的投资未来!
你有没有想过,在 Amazon(AMZN)这种"牛股"身上,除了长期持有还能玩出什么花样?
数据说话:2000 年 1 月到 2025 年 12 月,如果你只是简单地买入并持有 AMZN,你会收获 5616% 的回报,10 万美元变成 570 万美元,非常惊人。但代价是:在互联网泡沫破裂期间,你要眼睁睁看着账户缩水 93%,几乎归零。
今天给大家拆解一个更"聪明"的玩法 —— AMZN Connors-Bollinger 超卖反转策略。它只在市场恐慌时出手,其余时间拿着现金休息。最终 26 年跑出了 16334% 的收益,是买入持有的近 3 倍!
下面我们用 Python 一步步拆解这个策略,代码全部可复现。
这个策略的核心思想是:只在极度恐慌时买入。
它用两个指标做联合过滤:
入场条件:两个条件同时满足,次日开盘买入。出场条件:当再次出现"开盘跌破下轨"的信号时,次日开盘卖出。
import pandas as pdimport numpy as npimport yfinance as yfimport vectorbt as vbt# 下载 AMZN 从 2000 年到 2026 年的日线数据symbol = "AMZN"start_date = "2000-01-01"end_date = "2026-01-01"interval = "1d"df = yf.download(symbol, start=start_date, end=end_date, interval=interval)df.to_csv("AMZN_clean.csv", index=False)# 布林带参数:20 日周期,2 倍标准差BB_PERIOD = 20BB_STD = 2def calculate_bollinger_bands(df, period=BB_PERIOD, std_multiplier=BB_STD): """ 计算布林带的中轨、上轨和下轨 """ df = df.copy() # 中轨:20 日移动平均 df['BB_MA'] = df['Close'].rolling(window=period).mean() # 上轨:中轨 + 2 倍标准差 df['BB_Upper'] = df['BB_MA'] + std_multiplier * df['Close'].rolling(window=period).std() # 下轨:中轨 - 2 倍标准差 df['BB_Lower'] = df['BB_MA'] - std_multiplier * df['Close'].rolling(window=period).std() return dfdef bb_open_below_lower(df, period=BB_PERIOD, std_multiplier=BB_STD): # 判断开盘价是否跌破布林带下轨 df = calculate_bollinger_bands(df, period, std_multiplier) return df['Open'] < df['BB_Lower']ConnorsRSI 由三部分组成:经典 RSI、连续涨跌 RSI、百分位排名。
# ConnorsRSI 参数CRSI_RSI_OVERSOLD = 30 # 超卖阈值CRSI_RSI_PERIOD = 3 # RSI 周期CRSI_RSI_RANK_PERIOD = 100 # 百分位排名周期CRSI_RSI_STREAK_PERIOD = 2 # 连续涨跌 RSI 周期def connors_rsi(df, rsi_period=CRSI_RSI_PERIOD, streak_rsi_period=CRSI_RSI_STREAK_PERIOD, rank_period=CRSI_RSI_RANK_PERIOD): df = df.copy() # 1. 经典 RSI(基于价格变化) delta = df['Close'].diff() gain = delta.clip(lower=0) loss = -delta.clip(upper=0) avg_gain = gain.rolling(rsi_period).mean() avg_loss = loss.rolling(rsi_period).mean() rsi = 100 - (100 / (1 + (avg_gain / avg_loss + 1e-9))) # 2. 连续涨跌 RSI(基于连续上涨或下跌的天数) sign_diff = np.sign(delta) streak = sign_diff.groupby((sign_diff != sign_diff.shift()).cumsum()).cumsum() streak_rsi = streak.rolling(streak_rsi_period).apply( lambda x: 100 - (100 / (1 + (x.clip(lower=0).sum() / (-x.clip(upper=0).sum() + 1e-9)))) ) # 3. 100 日收益率百分位排名 roc = df['Close'].pct_change() rank = roc.rolling(rank_period).apply(lambda x: x.rank().iloc[-1] / len(x) * 100) # 三者取平均即为 ConnorsRSI df['ConnorsRSI'] = (rsi + streak_rsi + rank) / 3 return dfdef crsi_is_oversold(df, level=CRSI_RSI_OVERSOLD): # 判断 ConnorsRSI 是否处于超卖状态 df = connors_rsi(df) return df['ConnorsRSI'] < level# 生成入场条件:ConnorsRSI 超卖df["CRSI_Is_Oversold"] = crsi_is_oversold(df)# 生成出场条件:开盘跌破布林带下轨df["BB_Open_Below_Lower"] = bb_open_below_lower(df)# 入场信号与出场信号df['entry_signal'] = df["CRSI_Is_Oversold"]df['exit_signal'] = df["BB_Open_Below_Lower"]# 信号向后移一根 K 线,模拟次日开盘执行shift_entries = df['entry_signal'].shift(1).astype(bool).fillna(False).to_numpy()shift_exits = df['exit_signal'].shift(1).astype(bool).fillna(False).to_numpy()# 使用 vectorbt 进行回测pf = vbt.Portfolio.from_signals( close=df['Open'], # 以开盘价成交 entries=shift_entries, exits=shift_exits, init_cash=100_000, # 初始资金 10 万美元 fees=0.001, # 手续费 0.1% slippage=0.002, # 滑点 0.2% freq='1d')print(pf.stats())pf.plot().show()在 2000-01-03 至 2025-12-31 这 26 年间的表现:
| 16334% | ||
几个值得注意的亮点:
这个策略虽然回测漂亮,但也有几点要冷静看待:
建议:在实盘之前,还需要做 Walk-Forward 参数优化、多品种样本外测试,确认策略真的稳健,而不是"过拟合"出来的漂亮曲线。
这篇文章带大家用 Python 实现了一个经典的均值回归策略 —— 布林带 + ConnorsRSI 超卖反转。核心思路只有一句话:
在市场极度恐慌时买入,在下一次恐慌出现时卖出。
它告诉我们几个重要的交易哲学:
对 Python 量化感兴趣的朋友,可以把这个框架改一改,换成 TSLA、NVDA、META 等其他品种试一试,观察一下策略的适应性。记住:真正的 edge 不是代码本身,而是你对市场的理解。
2026年全面升级已落地!【数据科学实战】知识星球核心权益如下:
星球已沉淀丰富内容生态——涵盖量化文章专题教程库、因子日更系列、高频数据集、PyBroker实战课程、专家深度分享与实时答疑服务。无论您是初探量化的学习者,还是深耕领域的从业者,这里都是助您少走弯路、高效成长的理想平台。诚邀加入,共探数据驱动的投资未来!
好文推荐
1. 用 Python 打造股票预测系统:Transformer 模型教程(一)
2. 用 Python 打造股票预测系统:Transformer 模型教程(二)
3. 用 Python 打造股票预测系统:Transformer 模型教程(三)
4. 用 Python 打造股票预测系统:Transformer 模型教程(完结)
6. YOLO 也能预测股市涨跌?计算机视觉在股票市场预测中的应用
9. Python 量化投资利器:Ridge、Lasso 和 Elastic Net 回归详解
好书推荐