
用 Python 揭秘均值回归策略:你的收益从何而来?
2026年重磅升级已全面落地!欢迎加入专注财经数据与量化投研的【数据科学实战】知识星球!您将获取持续更新的《财经数据宝典》与《量化投研宝典》,双典协同提供系统化指引;星球内含 350 篇以上独有高质量文章,深度覆盖策略开发、因子分析、风险管理等核心领域,内容基本每日更新;同步推出的「量化因子专题教程」系列(含完整可运行代码与实战案例),系统详解因子构建、回测与优化全流程,并实现日更迭代。我们持续扩充独家内容资源,全方位赋能您的投研效率与专业成长。无论您是量化新手还是资深研究者,这里都是助您少走弯路、事半功倍的理想伙伴,携手共探数据驱动的投资未来!
你是否好奇量化交易者是如何用代码战胜市场的?最近读到一篇非常实在的开源项目分享:作者用 Python 构建了一套多因子选股系统,对约 100 只美股大盘股每月排名打分,选出前 10 名等权持有,在 2020 到 2025 年的回测中取得了 301% 的总收益和 1.08 的夏普比率。
但更难得的是,作者并没有炫耀这份漂亮的成绩单,而是坦诚地剖析了系统的缺陷:数据有幸存者偏差、因子选择存在过拟合、交易成本模型过于理想……本文将带你了解这套系统的设计思路、关键代码实现,以及作者的反思总结,希望能帮助正在学习 Python 量化的朋友少走弯路。
整套系统由 6 个模块组成,通过 YAML 配置文件管理所有参数,方便调整因子权重、再平衡频率等:
# 核心流程示意
data_fetch() # 1. 从 Yahoo Finance 抓取日线数据
compute_factors() # 2. 计算各类因子指标
composite_score() # 3. 合成打分并排名
build_portfolio() # 4. 选 Top 10 等权构建组合
run_backtest() # 5. 跑回测
generate_report() # 6. 输出分析报告和图表作者实现了 7 组因子,但默认只启用 3 组,权重分配如下:
被禁用的 4 组因子:
下面是一个简化版的因子合成打分逻辑,非常适合 Python 学习者参考:
import numpy as np
import pandas as pd
from scipy.stats import zscore
def winsorize(series, lower=0.01, upper=0.99):
"""对极值进行缩尾处理,避免单只异常股票扭曲整体分布"""
lo = series.quantile(lower) # 计算 1% 分位数
hi = series.quantile(upper) # 计算 99% 分位数
return series.clip(lower=lo, upper=hi)
def compute_composite_score(df, factor_weights):
"""
计算复合因子得分
df:包含各因子原始值的 DataFrame(每行是一只股票)
factor_weights:因子权重字典,例如 {"return_3m": 0.35, ...}
"""
score = pd.Series(0.0, index=df.index) # 初始化得分
for factor, weight in factor_weights.items():
# 步骤 1:缩尾去极值
clipped = winsorize(df[factor])
# 步骤 2:横截面 Z-score 标准化
standardized = zscore(clipped, nan_policy="omit")
# 步骤 3:按权重累加
score += weight * pd.Series(standardized, index=df.index)
return score
# 使用示例
factor_weights = {
"return_1m": 0.15, # 1 个月动量
"return_3m": 0.35, # 3 个月动量
"return_6m": 0.20, # 6 个月动量
"dist_ma50": 0.15, # 距 50 日均线
"dist_ma200": 0.10, # 距 200 日均线
"dollar_vol": 0.05, # 成交额
}
scores = compute_composite_score(stocks_df, factor_weights)
top_10 = scores.nlargest(10) # 选出得分最高的 10 只股票
print("本月入选股票:", top_10.index.tolist())每月最后一个交易日重新排名,选出前 10 只等权持有(每只 10%),两次再平衡之间让权重自然漂移。
def rebalance_portfolio(prev_weights, new_top10, prices):
"""
月度再平衡函数
prev_weights:上期持仓权重
new_top10:本期选出的前 10 只股票
prices:当期价格
"""
# 新组合等权分配
new_weights = pd.Series(0.1, index=new_top10)
# 计算单边换手率
all_tickers = prev_weights.index.union(new_weights.index)
turnover = (new_weights.reindex(all_tickers, fill_value=0)
- prev_weights.reindex(all_tickers, fill_value=0)).abs().sum() / 2
# 交易成本:10bps 佣金 + 5bps 滑点
cost_bps = 15
cost = turnover * cost_bps / 10000
return new_weights, turnover, cost
# 例如:50% 换手率对应约 7.5bps 的成本三次主要回撤:
这个项目最有价值的地方,不是那条漂亮的净值曲线,而是围绕它的一整套诊断工具——因子 IC、分层收益、换手分解、分市场状态的表现分析。这些工具能告诉你信号是否真实、在哪里会失效,而单看收益曲线是看不出来的。
对 Python 学习者的启发有三点:
如果你也在学 Python 量化,不妨把这个思路运用到自己的项目里:先搭好可插拔的框架,再用严谨的诊断方法持续审视自己的策略。
2026年全面升级已落地!【数据科学实战】知识星球核心权益如下:
星球已沉淀丰富内容生态——涵盖量化文章专题教程库、因子日更系列、高频数据集、PyBroker实战课程、专家深度分享与实时答疑服务。无论您是初探量化的学习者,还是深耕领域的从业者,这里都是助您少走弯路、高效成长的理想平台。诚邀加入,共探数据驱动的投资未来!
好文推荐
1. 用 Python 打造股票预测系统:Transformer 模型教程(一)
2. 用 Python 打造股票预测系统:Transformer 模型教程(二)
3. 用 Python 打造股票预测系统:Transformer 模型教程(三)
4. 用 Python 打造股票预测系统:Transformer 模型教程(完结)
6. YOLO 也能预测股市涨跌?计算机视觉在股票市场预测中的应用
9. Python 量化投资利器:Ridge、Lasso 和 Elastic Net 回归详解
好书推荐