第 12 章 · 02 回测框架对比


文档摘要

第 12 章 · 02 回测框架对比 本节摘要:本节讲回测框架的对比与选择,以及它们各自的坑。回测(backtesting)是把策略放到历史数据上模拟交易,评估绩效——这是量化研究从「想法」到「验证」的关键一步。回测框架分两大范式:向量化(vectorized,如 vectorbt)用矩阵运算一次性算出所有时点的策略收益,速度极快,适合快速原型与参数扫描,但难以精确模拟交易细节(订单、滑点、仓位);事件驱动(event-driven,如 zipline、backtrader)按时间顺序逐 bar 处理事件,精确模拟订单匹配、资金、持仓,贴近实盘,但速度慢。还有轻量级的 backtesting.py,介于两者之间。仓库资料/回测.

第 12 章 · 02 回测框架对比

本节摘要:本节讲回测框架的对比与选择,以及它们各自的坑。回测(backtesting)是把策略放到历史数据上模拟交易,评估绩效——这是量化研究从「想法」到「验证」的关键一步。回测框架分两大范式:向量化(vectorized,如 vectorbt)用矩阵运算一次性算出所有时点的策略收益,速度极快,适合快速原型与参数扫描,但难以精确模拟交易细节(订单、滑点、仓位);事件驱动(event-driven,如 zipline、backtrader)按时间顺序逐 bar 处理事件,精确模拟订单匹配、资金、持仓,贴近实盘,但速度慢。还有轻量级的 backtesting.py,介于两者之间。仓库资料/回测.md 列出了主流框架链接(backtrader/qlib/QUANTAXIS/QuantLib 等)。本节讲清两大范式的差异、主流框架特点、回测的常见坑(未来函数、Survivorship bias、成本、过拟合),以及如何根据需求选框架。

内容来源:仓库 资料/回测.md(回测框架链接清单),结合框架通用知识,知识结构化整理。

⚠️ 学习提示:回测的最大危险不是「算错」,而是「算得太对」——回测绩效漂亮往往是过拟合或数据错误的产物。一个可信的回测,必须严格处理未来函数、Survivorship bias、交易成本,并用样本外验证。对任何「夏普 > 2」的回测都保持怀疑。

学习目标

阅读完本节,你应当能够:

  1. 区分向量化事件驱动两大回测范式。
  2. 列举主流框架(vectorbt、backtrader、zipline、backtesting.py、qlib)及特点。
  3. 说清回测的常见坑(未来函数、Survivorship bias、成本、过拟合)。
  4. 根据需求选择合适框架
  5. 理解回测与实盘的差距来源

一、回测:从想法到验证

回测是把策略(「什么时候买、买多少、什么时候卖」)放到历史数据上模拟交易,看它的绩效如何。它是量化研究的核心环节:

  • 验证想法:策略在历史上是否赚钱。
  • 调参:找最优参数(但小心过拟合)。
  • 评估风险:最大回撤、夏普等。

但回测有个根本陷阱:历史不代表未来。一个在历史上表现完美的策略,可能只是过拟合了历史噪声,实盘中失效。所以回测的目的不是「证明策略有效」,而是「排除明显无效的策略,并对看似有效的策略保持怀疑」。

二、两大范式:向量化 vs 事件驱动

回测框架按实现方式分两大范式:

向量化(Vectorized)

  • 原理:把策略表达为向量/矩阵运算,用 NumPy/Pandas 一次性算出所有时点的信号与收益。
  • 代表:vectorbt、自写 Pandas 脚本。
  • 优势:速度极快(毫秒级测十年数据),适合参数扫描、快速原型。
  • 劣势:难以精确模拟交易细节——订单部分成交、滑点、资金约束、T+1 规则等,向量处理起来很别扭。

事件驱动(Event-driven)

  • 原理:按时间顺序逐 bar(或逐 tick)处理事件(新 K 线、订单、成交),模拟真实交易所的撮合过程。
  • 代表:backtrader、zipline(zipline-reloaded)、vnpy、QuantConnect。
  • 优势:精确模拟——订单类型、滑点、手续费、资金、持仓、T+1,贴近实盘。
  • 劣势:速度慢(逐 bar 循环),不适合大规模参数扫描。
维度 向量化 事件驱动
速度 极快(毫秒级) 慢(秒~分钟级)
精确度 低(难以模拟细节) 高(贴近实盘)
适合 原型、参数扫描、研究 最终验证、实盘对接
典型流程 先向量化扫参数 再事件驱动精验证

💡 核心心法:两种范式不是二选一,而是配合使用——研究阶段用向量化快速扫大量参数与想法,锁定候选策略后,再用事件驱动做精确验证。这是工业界标准流程。

三、主流框架对比

仓库 资料/回测.md 列出几个框架,加上主流开源,整理如下:

框架 范式 语言 特点
vectorbt 向量化 Python 极快,基于 NumPy,适合参数扫描、技术指标策略
backtrader 事件驱动 Python 老牌、社区大、文档全、灵活,适合股票/期货
zipline / zipline-reloaded 事件驱动 Python QuantFlow 出品,曾驱动 Quantopian,A 股需本土化
backtesting.py 轻量事件驱动 Python 极简、API 优雅、易上手,适合单策略快速验证
qlib 混合(偏 ML) Python 微软出品,AI 量化平台,内置数据+模型+回测(第 03 节)
vnpy 事件驱动 Python 国人开发,主打实盘交易(期货/股票),回测+实盘一体(第 03 节)
QUANTAXIS 事件驱动 Python 国内开源,A 股本土化好,数据+回测+实盘
QuantLib C++/Python 定价库(期权/固收),非通用回测框架

vectorbt(向量化代表)

  • 把策略写成信号矩阵(做多=1、做空=-1、空仓=0),用 portfolio.from_signals() 一行算出绩效。
  • 极适合「扫几千个参数组合」——分钟级完成。
  • 但不擅长复杂资金管理、多账户、订单簿细节。

backtrader(事件驱动代表)

  • 用 Cerebro 引擎驱动,Strategy 类写策略逻辑,Data Feed 喂数据,Broker 管资金与订单。
  • 支持复杂订单(限价、止损、OCO)、多账户、滑点与手续费模型。
  • 文档与社区成熟,但 API 略繁琐。

zipline-reloaded

  • Quantopian 原框架的维护版,与 pandas 深度集成。
  • TradingAlgorithm 写策略,按 handle_data 逐 bar 处理。
  • A 股需本土化(交易日历、涨跌停、T+1)。

backtesting.py

  • 极简,一个 Backtest 类 + 一个策略函数即可跑。
  • 适合「快速验证一个想法」,但不适合复杂多资产策略。

四、回测的常见坑

回测最大的危险不是算错,而是「算得太对」——以下是回测的几大坑:

未来函数(Look-ahead Bias)

未来函数是回测最常见、最致命的坑:在 T 时点用了 T 时点之后才知道的信息。

典型来源:

  • 财报数据用报告期而非发布日期:2023 年报在 2024 年 4 月才发布,若回测时在 2023 年 12 月 31 日就用这份年报数据,就是未来函数。
  • 复权用到未来:后复权用了未来除权信息。
  • 当日信号用当日 OHLC:在开盘时用了收盘价(未来)。
  • 统计量用全样本:用全样本均值标准化(包含未来),再回测。

应对:严格用「Point-in-time 数据」——每个时点只用那时已公开的信息。财报用发布日期对齐,信号只用历史窗口算的统计量。

Survivorship Bias(幸存者偏差)

Survivorship bias:回测时只用了「现存」的股票,忽略了已退市的股票,导致高估收益。

  • 退市股票通常是表现差的(亏损、违规),忽略它们等于只看「赢家」,收益被高估。
  • 应对:用包含退市股票的全样本数据(点时全集)。

交易成本

  • 手续费、滑点、冲击成本、买卖价差(第 11 章第 02 节)。
  • 日内/高频策略对成本极敏感,毛收益扣成本后可能为负。
  • 应对:扣费回测 + 成本敏感性分析。

过拟合(Overfitting)

  • 在大量参数组合里挑最优,「最优」可能是噪声(第 11 章第 04 节)。
  • 应对:样本外验证、walk-forward、CSCV/PBO、参数稳健性。

其他坑

  • 前视 tick:用 tick 数据时,tick 的时间戳与撮合顺序处理不当。
  • 资金约束:回测假设无限资金或忽略保证金,实盘做不到。
  • T+1 / 涨跌停:A 股特有规则,回测需正确处理(当日买入不能卖、涨跌停不能成交)。
  • 停牌:停牌期间不能交易,需正确处理(不能假设停牌时能买卖)。

五、向量化框架的「未来函数」陷阱

向量化框架(如 vectorbt)因为用矩阵运算,特别容易不小心引入未来函数:

  • .shift(-1)(未来值)做信号——直接用未来。
  • 用全样本标准化((x - x.mean()) / x.std() 用全样本均值)——含未来信息。
  • .rolling(...).mean() 时窗口包含当前 bar——当日信号用了当日价。

应对:

  • 滚动统计用 .rolling(...).mean().shift(1)——用截止昨日的统计,今日才用。
  • 标准化用滚动标准化(滚动窗口内标准化),而非全样本。
  • 信号生成后,把信号 shift(1),确保「今日信号 → 明日交易」。
# 错(未来函数): 今日信号用今日收盘 signal = (close > close.rolling(20).mean()) # 对(无未来): 今日用昨日收盘的信号 signal = (close > close.rolling(20).mean()).shift(1)

六、如何选择回测框架

根据需求选框架:

需求 推荐
快速扫参数/原型 vectorbt
单策略快速验证 backtesting.py
复杂多资产/订单 backtrader
A 股本土化研究 qlib / QUANTAXIS
AI 量化(ML 因子) qlib
回测+实盘一体 vnpy
期权/固收定价 QuantLib

七、回测与实盘的差距

即使最严谨的回测,与实盘仍有差距,来源:

  • 市场冲击:实盘中你的订单会推动价格,回测假设你是价格接受者。
  • 流动性:回测假设总能成交,实盘可能无对手方。
  • 延迟:实盘有数据、决策、下单延迟,回测瞬时。
  • 市场状态变化:历史的市场结构、规则、参与者可能已变化(制度变迁)。
  • 情绪:实盘有心理压力,回测没有。

💡 核心心法:回测是「必要但不充分」——回测不行的策略实盘肯定不行,但回测行的策略实盘未必行。从回测到实盘,需用小资金 forward test(前向测试),逐步加码,持续监控回测-实盘差距。

八、回测在本教程的角色

回测贯穿本教程:

  • 第 2 章因子:分层回测、IC 测试。
  • 第 3 章技术指标:main.py 的简单回测(分组胜率)。
  • 第 4~6 章 ML:模型预测 → 回测。
  • 第 11 章 CTA:日内/趋势策略的回测(成本敏感)。
  • 第 11 章第 04 节:回测过拟合与 CSCV。

理解回测的局限,是理解这些章节实证结论的前提——所有研报的漂亮数字,都需在「回测可信度」的框架下审视。

本节要点回顾

  1. 回测本质:策略放历史模拟;目的不是证明有效,而是排除无效并对有效保持怀疑。
  2. 两大范式:向量化(极快、不精确,适合扫参数)vs 事件驱动(精确、慢,贴近实盘);配合使用是工业标准。
  3. 主流框架:vectorbt(向量化)、backtrader/zipline/backtesting.py(事件驱动)、qlib(AI 量化)、vnpy(回测+实盘)、QuantLib(定价)。
  4. 常见坑:未来函数(用 Point-in-time 数据)、Survivorship bias(全样本含退市)、交易成本(扣费回测)、过拟合(样本外/CSCV)、T+1/涨跌停/停牌。
  5. 向量化陷阱:shift(-1)、全样本标准化、滚动窗口含当前 bar;应对用 shift(1)、滚动标准化。
  6. 选框架:扫参数→vectorbt,快速验证→backtesting.py,复杂→backtrader,A 股研究→qlib/QUANTAXIS,实盘→vnpy。
  7. 回测-实盘差距:冲击、流动性、延迟、制度变迁、情绪;需 forward test 小资金验证。

下一节,我们看开源量化工具链全景——qlib(AI 量化)、vnpy(交易)、FinRL(强化学习)、Riskfolio-Lib/PyPortfolioOpt(组合优化)、因子挖掘工具,对应量化研究各环节。


发布者: 作者: 灏天文库 转发
评论区 (0)
U