热启动 (Warm Start) 指南¶
AKQuant 提供了强大的热启动 (Warm Start) 功能,允许你保存回测引擎的当前状态(快照),并在未来某个时间点恢复该状态继续运行。这对于长周期策略的分段回测、滚动训练(Rolling Window)以及模拟实盘环境非常有用。
1. 什么是热启动?¶
在传统的事件驱动回测中,每次运行都是从头开始(Cold Start),所有状态(持仓、资金、指标历史)都需要从零积累。
热启动允许你: 1. 保存 (Snapshot): 将引擎的当前内存状态(包括持仓、未成交订单、策略变量、指标状态等)序列化保存到磁盘文件。 2. 恢复 (Resume): 从磁盘文件加载状态,恢复引擎和策略,就像中间没有中断过一样,接着处理新的数据。
2. 基本用法¶
2.1 保存快照 (Phase 1)¶
在第一阶段回测结束时(或在策略逻辑中任意时刻),调用 save_snapshot 保存状态。
from akquant.checkpoint import save_snapshot
# 运行第一阶段回测
result1 = run_backtest(data=data_phase1, strategy=MyStrategy, ...)
# 保存快照到文件
checkpoint_file = "checkpoint_phase1.pkl"
save_snapshot(result1.engine, result1.strategy, checkpoint_file)
print(f"Snapshot saved to {checkpoint_file}")
2.2 恢复并继续运行 (Phase 2)¶
使用 run_warm_start 函数从快照恢复,并传入第二阶段的数据。
注意:快照仅保存了动态状态(Portfolio, Orders, Strategy Attributes),不包含 静态配置(Instrument, MarketModel)。因此在恢复时,你必须重新配置这些静态信息。
import akquant as aq
# 准备第二阶段数据
data_phase2 = ...
# 从快照恢复并运行
result2 = aq.run_warm_start(
checkpoint_path="checkpoint_phase1.pkl",
data=data_phase2,
symbol="AAPL", # 你的主要标的
# 重要:必须重新传入市场费用配置,因为 MarketModel 不会被保存
commission_rate=0.0003,
stamp_tax=0.001,
t_plus_one=True # 如果是 A 股
)
3. 策略适配 (关键)¶
为了支持热启动,你的策略代码需要正确处理初始化 (Initialization) 和 恢复 (Restoration) 的区别。
3.1 生命周期钩子¶
AKQuant 为策略提供了两个关键的启动钩子:
on_start(): 无论冷启动还是热启动,都会调用。用于通用初始化(如订阅行情)。on_resume(): 仅在热启动时调用(在on_start之前)。用于恢复特定的连接或资源。
3.2 避免覆盖状态¶
最常见的错误是在 on_start 中无条件地重新初始化指标,导致从快照恢复的指标状态被覆盖(重置为 0)。
错误写法 ❌:
def on_start(self):
# 错误!如果从快照恢复,self.sma 已经有值了,这里会将其覆盖为新对象
self.sma = SMA(30)
self.subscribe(self.symbol)
正确写法 ✅:
使用 self.is_restored 属性判断当前是否为恢复模式。
def on_start(self):
# 1. 初始化指标 (仅在冷启动时)
if not self.is_restored:
self.sma = SMA(30)
# 初始化其他非持久化状态...
else:
self.log("Resumed from snapshot. Indicators retained.")
# 2. 注册指标 (必须执行,以便 Engine 知道需要更新它)
self.register_indicator("sma", self.sma)
# 3. 订阅行情 (必须执行,因为连接是临时的)
self.subscribe(self.symbol)
3.3 指标持久化¶
AKQuant 内置的指标(如 SMA, EMA)已经支持 Pickle 序列化。如果你使用自定义指标或第三方库(如 TA-Lib),请确保它们支持 pickle,或者在 __getstate__ 和 __setstate__ 中手动处理状态保存。
4. 注意事项¶
- Instrument 需重新注册:
run_warm_start会尝试自动为新数据中的 Symbol 注册默认 Instrument。如果你的策略依赖特定的lot_size或multiplier,建议在on_start中手动检查并调用self.ctx.engine.add_instrument(...)。 - MarketModel 重置:费用设置(佣金、印花税)和交易规则(T+1)不会保存在快照中。务必在
run_warm_start的kwargs中传入正确的参数。 - 初始资金显示:
result2.metrics.initial_cash会自动调整为恢复时的资金,确保收益率计算是基于第二阶段的实际起始资金,而不是账户的历史初始资金。 - 数据连续性:确保 Phase 1 的结束时间与 Phase 2 的开始时间是连续的。如果中间有长时间中断,指标计算可能会出现跳跃。
5. 完整示例¶
请参考项目中的 examples/21_warm_start_demo.py 获取完整的可运行代码。