问题描述
解决方案
在PTrade量化交易平台中,策略在遇到券商升级或环境重启后,框架会自动进行持久化信息的恢复。了解其恢复机制对于保证策略逻辑的连贯性至关重要。
1. 持久化信息的恢复顺序
当环境重启后恢复交易时,PTrade框架的执行顺序如下:
- 首先执行策略的
initialize函数:框架会先运行初始化函数,重新声明和赋值基础变量。 - 然后执行持久化信息恢复操作:框架会读取之前保存的持久化信息(通常是使用
pickle模块保存的全局对象g中的变量)。
2. 变量覆盖规则
由于恢复操作在 initialize 之后执行,如果持久化信息中保存了策略定义的全局对象 g 中的某个变量,那么恢复时,持久化信息中的变量值将会覆盖掉 initialize 函数中初始化的该变量值。
例如,如果在 initialize 中设置了 g.count = 0,但在重启前持久化保存的 g.count 值为 5,那么重启恢复后,g.count 的值将是 5。
3. 持久化注意事项与私有变量
在处理持久化时,需要特别注意以下几点:
- 不可序列化的对象:涉及到IO操作的对象(如打开的文件、实例化的类对象、数据库连接等)是不能被序列化的。如果将这些对象直接挂载到
g上,会导致持久化失败。 - 私有变量(跳过持久化):为了防止不可序列化的变量导致报错,或者防止某些变量被持久化信息覆盖,您可以在
initialize中初始化该变量时,名字以__(双下划线)开头。全局变量g中以__开头的变量被视为私有变量,持久化时将不会被保存。
4. 示例代码
以下示例展示了如何处理不可序列化的类对象,使其在重启时正常初始化而不参与持久化:
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在重启后会先走 initialize 再覆盖持久化数据,开发者需合理利用 __ 私有变量前缀来管理不需要或不能被持久化的对象。