第 12 章 · 02 回测框架对比 本节摘要:本节讲回测框架的对比与选择,以及它们各自的坑。回测(backtesting)是把策略放到历史数据上模拟交易,评估绩效——这是量化研究从「想法」到「验证」的关键一步。回测框架分两大范式:向量化(vectorized,如 vectorbt)用矩阵运算一次性算出所有时点的策略收益,速度极快,适合快速原型与参数扫描,但难以精确模拟交易细节(订单、滑点、仓位);事件驱动(event-driven,如 zipline、backtrader)按时间顺序逐 bar 处理事件,精确模拟订单匹配、资金、持仓,贴近实盘,但速度慢。还有轻量级的 backtesting.py,介于两者之间。仓库资料/回测.
本节摘要:本节讲回测框架的对比与选择,以及它们各自的坑。回测(backtesting)是把策略放到历史数据上模拟交易,评估绩效——这是量化研究从「想法」到「验证」的关键一步。回测框架分两大范式:向量化(vectorized,如 vectorbt)用矩阵运算一次性算出所有时点的策略收益,速度极快,适合快速原型与参数扫描,但难以精确模拟交易细节(订单、滑点、仓位);事件驱动(event-driven,如 zipline、backtrader)按时间顺序逐 bar 处理事件,精确模拟订单匹配、资金、持仓,贴近实盘,但速度慢。还有轻量级的 backtesting.py,介于两者之间。仓库资料/回测.md 列出了主流框架链接(backtrader/qlib/QUANTAXIS/QuantLib 等)。本节讲清两大范式的差异、主流框架特点、回测的常见坑(未来函数、Survivorship bias、成本、过拟合),以及如何根据需求选框架。
内容来源:仓库 资料/回测.md(回测框架链接清单),结合框架通用知识,知识结构化整理。
⚠️ 学习提示:回测的最大危险不是「算错」,而是「算得太对」——回测绩效漂亮往往是过拟合或数据错误的产物。一个可信的回测,必须严格处理未来函数、Survivorship bias、交易成本,并用样本外验证。对任何「夏普 > 2」的回测都保持怀疑。
阅读完本节,你应当能够:
回测是把策略(「什么时候买、买多少、什么时候卖」)放到历史数据上模拟交易,看它的绩效如何。它是量化研究的核心环节:
但回测有个根本陷阱:历史不代表未来。一个在历史上表现完美的策略,可能只是过拟合了历史噪声,实盘中失效。所以回测的目的不是「证明策略有效」,而是「排除明显无效的策略,并对看似有效的策略保持怀疑」。
回测框架按实现方式分两大范式:
| 维度 | 向量化 | 事件驱动 |
|---|---|---|
| 速度 | 极快(毫秒级) | 慢(秒~分钟级) |
| 精确度 | 低(难以模拟细节) | 高(贴近实盘) |
| 适合 | 原型、参数扫描、研究 | 最终验证、实盘对接 |
| 典型流程 | 先向量化扫参数 | 再事件驱动精验证 |
💡 核心心法:两种范式不是二选一,而是配合使用——研究阶段用向量化快速扫大量参数与想法,锁定候选策略后,再用事件驱动做精确验证。这是工业界标准流程。
仓库 资料/回测.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 | 定价库(期权/固收),非通用回测框架 |
portfolio.from_signals() 一行算出绩效。TradingAlgorithm 写策略,按 handle_data 逐 bar 处理。Backtest 类 + 一个策略函数即可跑。回测最大的危险不是算错,而是「算得太对」——以下是回测的几大坑:
未来函数是回测最常见、最致命的坑:在 T 时点用了 T 时点之后才知道的信息。
典型来源:
应对:严格用「Point-in-time 数据」——每个时点只用那时已公开的信息。财报用发布日期对齐,信号只用历史窗口算的统计量。
Survivorship bias:回测时只用了「现存」的股票,忽略了已退市的股票,导致高估收益。
向量化框架(如 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(前向测试),逐步加码,持续监控回测-实盘差距。
回测贯穿本教程:
理解回测的局限,是理解这些章节实证结论的前提——所有研报的漂亮数字,都需在「回测可信度」的框架下审视。
下一节,我们看开源量化工具链全景——qlib(AI 量化)、vnpy(交易)、FinRL(强化学习)、Riskfolio-Lib/PyPortfolioOpt(组合优化)、因子挖掘工具,对应量化研究各环节。