社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

别再被回测骗了!用 Python 走查法实战检验 3 大回归模型

数据科学实战 • 3 月前 • 151 次点击  


 

 用 Python 揭秘均值回归策略:你的收益从何而来?



 

 

 

 

 

 

2026年重磅升级已全面落地!欢迎加入专注财经数据与量化投研的【数据科学实战】知识星球!您将获取持续更新的《财经数据宝典》与《量化投研宝典》,双典协同提供系统化指引;星球内含 500 篇以上独有高质量文章,深度覆盖策略开发、因子分析、风险管理等核心领域,内容基本每日更新;同步推出的「量化因子专题教程」系列(含完整可运行代码与实战案例),系统详解因子构建、回测与优化全流程,并实现日更迭代。我们持续扩充独家内容资源,全方位赋能您的投研效率与专业成长。无论您是量化新手还是资深研究者,这里都是助您少走弯路、事半功倍的理想伙伴,携手共探数据驱动的投资未来!

引言

每个交易者都有自己的「直觉」:某只股票该涨了,某个形态要出现反转了……但当你把感性剥离,让纯数学来交易,会发生什么?

更要命的是,大多数人做策略回测时都会犯一个致命错误 —— 用全部历史数据训练模型,再用同一段历史去验证。模型「偷看」了未来,回测结果漂亮得不真实,一上实盘就原形毕露。这就是著名的 look-ahead bias(前视偏差)

今天这篇文章,我们用 Python 搭建一个 走查法(Walk-Forward)仿真引擎,让 Kernel Regression、SVR、Ridge Regression 这 3 个回归模型在 NVIDIA(NVDA)的真实周线数据上「同台竞技」,看看哪个才是真金不怕火炼。

结果可能会颠覆你的认知:最简单的 Ridge 线性回归,反而打败了机器学习味十足的 SVR


一、什么是走查法?为什么必须用它?

走查法的核心,是模拟真实交易场景:模型只能看到「当下之前」的数据,绝不允许偷看未来。具体步骤如下:

  1. 1. 设定训练窗口:本案例用 24 根周线(约 6 个月)作为回看窗口。
  2. 2. 滚动训练:在第 t 周时,模型只能用 t-24 到 t-1 这 24 根周线训练。
  3. 3. 单步预测:模型预测第 t+1 周的收盘价,然后被「丢弃」。
  4. 4. 信号闸门:将预测涨跌幅与模型自身的 RMSE × 1.5 比较,弱信号直接过滤。
  5. 5. 记录真实结果:等第 t+1 周真正收盘后,再记录盈亏。
  6. 6. 窗口前移,循环重复:125 周数据 + 24 周窗口 = 100 次独立的样本外预测。

这套「训练 — 预测 — 揭晓」的循环,是目前公认最诚实的策略验证方式。


二、ROI 是怎么算的?

为了让对比公平,引擎使用 固定 1 股 的仓位逻辑:

  • • 信号触发时买入或做空 恰好 1 股
  • • 1 周后无条件平仓
  • • 每周回归 100% 现金,不做复利

单笔 ROI 公式

其中 Direction 在做多时为 +1,做空时为 -1。

整体策略 ROI


三、手把手搭建引擎

Step 1:抓取数据并重采样到周线

import yfinance as yf
import
 pandas as pd

# 从 Yahoo Finance 拉取 NVDA 日线数据

raw_df = yf.download("NVDA", start="2024-01-01", end="2026-06-25")
daily_df = raw_df[['Close']].ffill().dropna()

# 重采样为每周五收盘价,共 125 根周线

df = daily_df.resample('W-FRI').last().dropna()

Step 2:走查滚动主循环

import numpy as np

WINDOW_SIZE = 24  # 训练窗口 24 周

for
 t in range(WINDOW_SIZE, len(df) - 1):
    # 训练样本:截至 t-1 的 24 周历史

    history_df = df.iloc[t - WINDOW_SIZE : t]
    current_price = history_df['Close'].iloc[-1]

    # 样本外目标:1 周后的真实收盘价(预测时不可见)

    next_close = df['Close'].iloc[t]
    realized_move = next_close - current_price

    # 准备训练数据

    X_train = np.arange(len(history_df)).reshape(-1, 1)
    y_train = history_df['Close'].values
    next_idx = np.array([[len(history_df)]])

关键点:realized_move 是在预测之后才计算的,模型在预测时绝看不到它。

Step 3:3 个模型同台 PK




    
import statsmodels.api as sm
from
 sklearn.svm import SVR
from
 sklearn.linear_model import Ridge

# 模型 1:核回归(非参数,Nadaraya-Watson)

kernel_model = sm.nonparametric.KernelReg(
    endog=y_train, exog=X_train, var_type='c', bw=[4.0])
kernel_pred, _ = kernel_model.fit(next_idx)

# 模型 2:支持向量回归(RBF 核技巧,捕捉非线性)

svr_model = SVR(kernel='rbf', C=1e3, gamma=0.05)
svr_model.fit(X_train, y_train)
svr_pred = svr_model.predict(next_idx)[0]

# 模型 3:岭回归(带 L2 正则的线性模型)

ridge_model = Ridge(alpha=10.0)
ridge_model.fit(X_train, y_train)
ridge_pred = ridge_model.predict(next_idx)[0]

Step 4:1.5-sigma 噪声闸门

# 用样本内 RMSE 作为模型不确定性的代理
rmse_val = np.sqrt(np.mean((y_train - model.predict(X_train)) ** 2))

# 信号阈值:模型自身误差的 1.5 倍

noise_threshold = rmse_val * 1.5
projected_move = pred_val - current_price

# 只有当预测幅度 > 噪声阈值时才交易

signal_valid = abs(projected_move) >= noise_threshold

# 计算单笔 ROI(信号无效则为 0)

trade_roi = (realized_move * direction / current_price) * 100 \
    if
 signal_valid else 0

巧妙之处:拟合越差的模型(高 RMSE)会自动给自己设更高的门槛,相当于「自我打分」。


四、最终战绩:颠覆直觉的结果

经过 125 周 NVDA 真实数据的洗礼,3 个模型成绩如下:

模型
总交易数
胜率
累计盈亏
ROI
Kernel Regression
6
50.00%
+$7.61
+5.23%
Ridge(线性)2948.28%+$37.20+24.85%
SVR(机器学习)
50
38.00%
-$92.74
-61.97%

发现了吗?

  • • 交易最少的 Kernel 小赚一笔
  • • 最复杂的 SVR 亏到怀疑人生
  • • 最朴素的 Ridge 反而是最大赢家

为什么 SVR 翻车了?

SVR 的 RBF 核太「敏感」:它在 24 周里硬是要找出复杂曲线,结果不断被反转打脸,每周都在 LONG/SHORT 之间反复横跳,胜率仅 38%。

为什么 Ridge 赢了?

NVDA 在 2025 年走出了一波明显的上升趋势,Ridge 的「直线假设」恰好踩中节奏。在 9—10 月那段从 187 的行情里,它连续多周给出 LONG 信号,吃到了主升浪。

案例:Kernel 的经典一击

日期:2025-04-18 | 方向:SHORT | 入场:$110.90 | 出场:$101.47 | ROI:+8.51%

Kernel 在 2024 年中段震荡市几乎不开仓(信号不过闸门),2025 年 4 月却精准捕捉到一次下跌,单笔赚回 +8.51%。


五、5 条系统化交易铁律

  1. 1. 精选胜过频繁:高确信度的少量交易,几乎总能跑赢「广撒网」。噪声闸门不只是过滤器,它本身就是策略。
  2. 2. 复杂 ≠ 有效:SVR 的高级核技巧反而败给了一根直线。在小样本场景,简单模型泛化能力更强。
  3. 3. 走查法不可妥协:只有真实的样本外测试,才能暴露过拟合灾难。
  4. 4. 自适应阈值防盲区:基于 RMSE 的闸门让模型自己给自己评分,无需手动调参。
  5. 5. 趋势决定一切:Ridge 赢在 NVDA 的单边上行;如果换成震荡市,结果可能完全相反。

总结

这套走查法仿真引擎的真正价值,不是「告诉你哪个模型最好」,而是 给你一把诚实的尺子。代码完全模块化,你只需要换一个股票代码、换一个日期区间,就能在任何标的上做属于自己的「模型对决」。

下次再有人吹自己的策略 ROI 多高,先问一句:「你是走查法测的吗?」

想动手实战?把训练窗口从 24 周改成 12 周或 36 周试试,看看 Ridge 的趋势跟随能力是否会变得更稳。


参考文章

加入专注于财经数据与量化投研的知识星球【数据科学实战】,获取本文完整研究解析、代码实现细节。

财经数据与量化投研知识社区

2026年全面升级已落地!【数据科学实战】知识星球核心权益如下:

  1. 1. 双典系统赋能:获赠《财经数据宝典》与《量化投研宝典》完整文档,凝练多年实战经验,构建系统化知识框架;
  2. 2. 量化因子日更教程(2026重磅新增):每日更新「量化因子专题教程」,配套完整可运行代码与实战案例,深度拆解因子构建、回测与优化全流程;
  3. 3. 量化文章专题教程库:500+篇星球独有高质量教程式文章,系统覆盖策略开发、因子研究、风险管理等核心领域,内容基本每日更新,并配套精选学习资料与实战参考;
  4. 4. 量化投研实战课程:赠送《AKQuant-入门及实战》《PyBroker-入门及实战》视频课程,手把手教学,快速掌握量化策略开发技能;
  5. 5. 财经数据支持:定期更新国内外财经数据,为策略研发提供精准、可靠的数据基础;
  6. 6. 顶尖学者与行业专家分享:年度邀请学术界博士与业界资深专家开展前沿论文精讲与实战案例分享,不少于4场,直击研究前沿与产业实践;
    专家直连答疑:与核心开发者及领域专家实时互动,高效解决投研实战难题;
  7. 7. 专业社群与专属福利:加入高质量交流社群,获取课程折扣及更多独家资源。

星球已沉淀丰富内容生态——涵盖量化文章专题教程库、因子日更系列、高频数据集、PyBroker实战课程、专家深度分享与实时答疑服务。无论您是初探量化的学习者,还是深耕领域的从业者,这里都是助您少走弯路、高效成长的理想平台。诚邀加入,共探数据驱动的投资未来!

 

好文推荐

1. 用 Python 打造股票预测系统:Transformer 模型教程(一)

2. 用 Python 打造股票预测系统:Transformer 模型教程(二)

3. 用 Python 打造股票预测系统:Transformer 模型教程(三)

4. 用 Python 打造股票预测系统:Transformer 模型教程(完结)

5. 揭秘隐马尔可夫模型:因子投资的制胜武器

6. YOLO 也能预测股市涨跌?计算机视觉在股票市场预测中的应用

7. 金融 AI 助手:FinGPT 让你轻松掌握市场分析

8. 量化交易秘籍:为什么专业交易员都在用对数收益率?

9. Python 量化投资利器:Ridge、Lasso 和 Elastic Net 回归详解

10. 掌握金融波动率模型:完整 Python 实现指南

好书推荐


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/196912