🚀 AI 一键生成 ptrade 策略代码
立即体验
👉 AI 生成代码 👈

PTrade模拟盘或实盘重启后,策略变量为什么会被重置?如何解决?

ptrade | 发布时间: 2026/6/1
以下内容由 EasyQuant 生成。

问题描述

PTrade模拟盘或实盘重启后,策略变量为什么会被重置?

解决方案

在PTrade模拟盘或实盘运行过程中,如果遇到券商服务器升级或环境重启,策略变量可能会被重置或丢失。这通常与PTrade的持久化机制以及变量的序列化特性有关。

变量被重置的核心原因

  1. 重启后的执行顺序
    当环境重启恢复交易时,PTrade框架会先执行策略的 initialize 函数,然后再执行持久化信息的恢复操作。如果你的变量没有被成功持久化,那么它就会保持 initialize 中初始化的默认状态,看起来就像是被重置了。

  2. 变量未保存在全局对象 g
    PTrade框架只会自动对全局对象 g 中定义的变量进行持久化保存(使用 pickle 模块)。如果你使用了普通的全局变量(如 global var_name),这些变量在重启后会丢失。

  3. 变量无法被序列化
    框架在 before_trading_starthandle_dataafter_trading_end 事件后会触发持久化保存。但如果 g 中的变量不能被序列化(例如涉及到IO操作的打开文件、实例化的自定义类对象等),该变量将不会被保存。重启后,它只能保持 initialize 中的初始值。

  4. 使用了私有变量命名
    在PTrade中,全局变量 g 中以双下划线 __ 开头的变量被视为私有变量,持久化时将不会被保存

如何解决变量重置问题?

1. 正确使用全局对象 g

确保所有需要在交易日之间或重启后保留状态的变量,都挂载在 g 对象下,并且是基本数据类型(如 int, float, str, list, dict 等可序列化对象)。

def initialize(context):
    # 正确做法:使用 g 对象
    g.buy_count = 0
    g.security = '600570.SS'
    set_universe(g.security)

2. 规避不可序列化对象

如果必须在 initialize 中初始化无法被序列化的类对象,请将其命名为以 __ 开头的私有变量,这样框架在落地持久化信息时会跳过它,避免引发序列化错误。

class Test(object):
    count = 5

def initialize(context):
    # 初始化无法被序列化类对象,并赋值为私有变量
    g.__test_class = Test()

3. 手动使用 pickle 进行持久化(推荐用于复杂逻辑)

对于复杂的策略状态(如记录持仓天数、复杂的字典结构),建议在策略中手动使用 pickle 模块将数据保存到研究路径下。这样即使框架的自动持久化出现问题,也能从文件中恢复。

import pickle
from collections import defaultdict

NOTEBOOK_PATH = get_research_path()

def initialize(context):
    g.security = '600570.SS'
    set_universe(g.security)
    # 尝试从本地文件恢复变量
    try:
        with open(NOTEBOOK_PATH + 'hold_days.pkl', 'rb') as f:
            g.hold_days = pickle.load(f)
    except:
        g.hold_days = defaultdict(list)

def handle_data(context, data):
    # 策略逻辑...
    
    # 每天/每次逻辑变化后,手动将变量进行pickle保存
    with open(NOTEBOOK_PATH + 'hold_days.pkl', 'wb') as f:
        pickle.dump(g.hold_days, f, -1)

4. 注意 set_parameters 的重启配置

在实盘交易中,为了防止服务器重启导致 initializebefore_trading_start 被重复调用从而引发逻辑混乱(如重复委托),建议在 initialize 中配置防重启参数:

def initialize(context):
    # not_restart_trade="1": 交易时间段若服务器重启,不自动执行重新拉起本交易
    # server_restart_not_do_before="1": 若服务器重启导致重拉交易,不重复执行before_trading_start函数
    set_parameters(not_restart_trade="1", server_restart_not_do_before="1")

总结:要防止PTrade策略变量在重启后重置,核心是确保变量可序列化正确挂载在 g 对象上,并在必要时结合本地文件手动持久化