在选择具体的回测框架之前,我们必须先理解所有框架背后共同的“灵魂”——它们的回测逻辑。目前,主流的回测框架主要分为两大流派:事件驱动 (Event-Driven) 和 向量化 (Vectorized)。理解它们的区别,将直接决定你选择哪个框架,甚至影响你设计策略的思路。
流派一:事件驱动 (Event-Driven) —— 精密模拟,步步为营
事件驱动回测,顾名思义,它的核心是一个事件循环 (Event Loop)。它就像一个勤劳的钟表匠,把时间一格一格地往前拨。在每个时间点(比如每一根K线的收盘),它会产生一个“市场数据事件”,然后把它发送给你的策略。
- 工作流程:
系统从数据源取出第一条数据(比如第一天的K线)。
将数据打包成一个“事件”,放入事件队列。
系统从队列中取出事件,交给你的策略的 next() 方法处理。
你的策略在 next() 中根据当前数据和已有仓位,判断是否要下单。
如果要下单,策略会生成一个“订单事件”,发给模拟的“交易所”。
“交易所”处理订单,生成“成交事件”,并更新你的持仓和现金。
循环回到第1步,取出下一条数据,直到数据处理完毕。
- 优点:
高度拟真: 最接近真实交易的逻辑,可以非常精细地模拟滑点、佣金、订单撮合等复杂情况。
逻辑灵活: 可以轻松实现复杂的逻辑,比如动态仓位管理、依赖路径的止盈止损、多策略组合等。
无缝切换: 由于逻辑与实盘高度一致,从回测切换到实盘交易通常更容易。
- 缺点:
速度较慢: 大量的循环和判断使得其运行速度远慢于向量化回测。
- 代表框架:
Backtrader
,Zipline
,vn.py
流派二:向量化 (Vectorized) —— 运筹帷幄,一击制胜
向量化回测则完全是另一种思路。它不关心过程,只关心结果。它利用 Numpy 和 Pandas 的强大向量化计算能力,一次性地处理所有历史数据。
- 工作流程:
将所有历史价格数据加载到一个大的 DataFrame 或 Numpy 数组中。
用向量化操作,一次性地计算出整个时间序列的交易信号(比如,一个代表买入卖出的 [0, 1, -1, 0, ...]
序列)。
用向量化操作,计算出策略的每日收益率序列。
将每日收益率序列累积起来,得到最终的净值曲线和各项绩效指标。
- 优点:
速度极快: 由于避免了 Python 的 for 循环,其速度可以比事件驱动快成百上千倍,非常适合做大规模的参数优化和因子筛选。
- 缺点:
逻辑受限: 很难模拟复杂的、依赖路径的交易行为。例如,一个“如果连续亏损3天就空仓”的规则,用向量化就极难实现。
容易引入未来函数: 在进行向量化计算时,稍不注意就可能用到当前时间点之后的数据(例如,用当日收盘价计算的信号,却在当日开盘时交易),导致回测结果虚高。
抽象层级高: 离真实交易的逻辑较远。
- 代表框架:
vectorbt
我该如何选择?
不存在哪个流派“更好”,只有哪个“更适合”你的当前任务。
当你处于策略的探索和筛选阶段,需要快速验证大量因子和参数时,向量化回测 (vectorbt) 是你的不二之选。它能让你在几分钟内完成数万次回测。
当你已经有了一个初步成型的策略,需要精细地打磨交易逻辑、模拟真实成本、并为实盘做准备时,事件驱动回测 (Backtrader) 更加可靠和灵活。
一个专业的量化工作流,往往是两者结合:先用向量化工具进行大规模的探索,找到有潜力的策略方向;然后用事件驱动框架对选出的策略进行精细的回测和验证。