问题描述
解决方案
在PTrade量化交易平台中,框架默认会在特定事件(如before_trading_start、handle_data、after_trading_end)后触发持久化操作,使用pickle模块保存全局对象g中的变量。但有时我们需要存储一些无法被序列化的对象(如打开的文件、实例化的类对象、网络连接等),或者仅仅是临时变量不需要保存。
要让某些变量不被持久化保存,核心方法是将变量名以双下划线 __ 开头。
核心规则
- 私有变量标识:在全局变量
g中,以__开头的变量被视为私有变量,持久化时将不会被保存。 - 避免序列化报错:涉及到IO(打开的文件,实例化的类对象等)的对象是不能被序列化的,必须使用
__开头来定义,否则会导致策略运行报错。 - 重启恢复逻辑:券商升级或环境重启后恢复交易时,框架会先执行策略的
initialize函数,再执行持久化信息恢复操作。如果普通变量被持久化了,恢复时会覆盖initialize中的初始值;而__开头的变量则会保持initialize中的初始化状态。
代码示例
以下是一个完整的示例,展示了如何定义和使用不被持久化的私有变量:
# 定义一个无法被直接序列化的自定义类
class Test(object):
count = 5
def print_info(self):
self.count += 1
log.info("a" * self.count)
def initialize(context):
g.security = "600570.SS"
set_universe(g.security)
# 初始化无法被序列化类对象,并赋值为私有变量(以 __ 开头)
# 落地持久化信息时,框架会跳过保存该变量
g.__test_class = Test()
def handle_data(context, data):
# 调用私有变量中定义的方法
g.__test_class.print_info()
总结
在编写PTrade策略时,合理区分需要跨日/跨重启保存的状态变量(如仓龄、自定义持仓记录)和不需要保存的运行时对象(如类实例、临时计算结果)。对于后者,务必使用 g.__变量名 的形式进行声明,以保证策略的稳定运行。