问题描述
解决方案
在 PTrade 量化交易框架中,持久化信息的更新和保存是非常关键的机制,它确保了策略在重启或跨日运行时能够保持状态的连贯性。
持久化信息更新的触发时机
根据 PTrade API 文档,框架会在以下 三个核心事件执行完毕后 自动触发持久化信息的更新及保存操作:
before_trading_start(盘前事件/隔日开始)handle_data(盘中事件)after_trading_end(盘后事件)
在这些事件函数执行结束后,框架会使用 pickle 模块自动保存当前的股票池、账户信息、订单信息以及全局变量 g 中定义的变量等内容。
持久化处理的重要注意事项
为了避免策略在实盘或模拟盘中出现状态丢失或异常,您需要注意以下几点:
- 重启恢复机制:当券商系统升级或环境重启后恢复交易时,框架会先执行策略的
initialize函数,然后再执行持久化信息恢复操作。这意味着,如果持久化信息中保存了全局对象g中的某个变量,它将会覆盖掉initialize函数中初始化的同名变量。 - 不可序列化对象:全局变量
g中不能被序列化(pickle)的变量将不会被保存。例如,涉及到 IO 操作的对象(如打开的文件、实例化的类对象、数据库连接等)是无法被序列化的。 - 私有变量跳过保存:如果您在
initialize中初始化了无法被序列化的变量,建议将其命名为以__(双下划线)开头的私有变量(例如g.__test_class)。框架在持久化时会自动跳过保存这些私有变量。
自定义持久化示例
除了框架自动保存 g 对象外,您也可以在策略中手动使用 pickle 模块将特定数据落地到文件中,以实现更灵活的状态管理:
import pickle
from collections import defaultdict
NOTEBOOK_PATH = get_research_path()
def initialize(context):
# 尝试从本地文件恢复自定义的持久化变量
try:
with open(NOTEBOOK_PATH + 'hold_days.pkl', 'rb') as f:
g.hold_days = pickle.load(f)
except:
g.hold_days = defaultdict(list)
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
# 策略逻辑...
# 每天手动将存储状态的字典对象进行 pickle 保存
with open(NOTEBOOK_PATH + 'hold_days.pkl', 'wb') as f:
pickle.dump(g.hold_days, f, -1)
掌握 PTrade 的持久化触发时机和规则,是编写稳定、可靠的实盘量化策略的基础。