6. 回测引擎与性能

本章从使用与结果角度说明 qteasy 的回测引擎如何工作,以及性能与向量化的实现方式,便于用户理解回测速度与正确性的来源。更底层的架构说明见《架构与设计》中的 回测引擎与性能(设计视角)

6.1. 1. 回测引擎概览

回测入口与流程已在 回测概览如何运行回测 中说明:通过 qt.run(op, mode=1, ...) 进入回测模式,内部按 group_timing_table 的每个时间步运行策略、解析信号并模拟成交。

与“逐 bar 事件驱动”或“全时间轴一次性矩阵运算”不同,qteasy 采用 时间维顺序步进、单步内标的维向量化 的方式:

  • 时间维:按真实交易节奏顺序执行每个时间步,以正确维护现金、持仓、交割队列(如 T+1)等状态。

  • 标的维:在每个时间步内,对资产池中所有标的的买卖量、费用、持仓更新等做 向量化计算(NumPy 数组 + Numba 加速),单步效率高。

这样既保证了与实盘一致的状态与规则,又避免了纯事件驱动下的逐笔循环带来的性能损失。

6.2. 2. 性能与向量化

2.1 核心计算加速

回测与交易结果计算中的以下核心函数均使用 Numba JIT@njit(nogil=True, cache=True))加速:

  • backtest_step:单步内对整批标的计算买卖量、费用、持仓与交割更新。

  • calculate_trade_results:交易结果与资金变动计算。

  • backtest_batch_steps:在 Numba 内按时间步循环调用 backtest_step,完成整段回测。

  • backtest_flash_steps:优化模式下使用,仅保留最终资金与持仓以节省内存,同样在 Numba 内完成批量步进。

信号混合(如多策略合并)在 blender 模块中部分算子也使用 @njit 加速。因此,回测主体是 向量化 + Numba 实现的,而非纯 Python 循环。

2.2 时间维顺序与标的维向量化

维度

做法说明

时间维

顺序步进,以正确维护 T+1、交割周期、MOQ 等状态,与实盘一致。

标的维

单步内对所有标的做数组运算(如 op_signalown_amounts 等为 1D 数组),实现向量化。

优化模式

多组参数通过多进程并行回测;每组内部使用 backtest_flash_steps 等高效路径,减少内存与计算。

首次运行或参数变化时,Numba 会编译相关函数,可能带来一次性的启动延迟;后续同类型回测会复用缓存,速度更快。

2.3 与 VectorBT 的简要对比

对比项

qteasy

VectorBT

时间维

顺序步进,每步内向量化

全时间轴一次性矩阵运算,无显式时间循环

状态与约束

显式维护 T+1、交割、MOQ 等,贴近实盘

多为简化资金曲线,不强调交割/MOQ

适用场景

需要正确模拟 A 股规则、多策略合并、精细成本与交割时

海量参数组合快速筛选、研究向回测

qteasy 在保证状态正确性与规则可配置的前提下,通过时间维顺序 + 标的维向量化 + Numba 单步,兼顾速度;多组参数优化则通过多进程并行弥补“单次不能全矩阵广播”的差异。

6.3. 3. 本目录与相关文档