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

ptrade 怎么防止服务器重启的时候 initialize 把我策略盘中的全局变量覆盖掉?

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

问题描述

ptrade 实盘不重置:如何避免服务器重启导致 initialize 全局变量重置?
ptrade 怎么防止服务器重启的时候 initialize 把我策略盘中的全局变量覆盖掉?

解决方案

在 ptrade 实盘交易中,券商系统升级或服务器环境重启是常见情况。默认情况下,系统重启后会先执行策略的 initialize 函数,再执行持久化信息恢复操作。如果我们在 initialize 中对全局变量 g 进行了初始化,这些变量可能会覆盖掉持久化恢复中的最新状态,导致策略逻辑混乱。

为了防止服务器重启时 initialize 覆盖掉策略盘中的全局变量,我们可以通过以下两种核心方案进行解决:

方案一:使用 set_parameters 限制重启行为(推荐)

ptrade 提供了专门的配置参数,用于在交易时间内避免重复执行初始化和盘前函数。你可以在 initialize 中使用 set_parameters 进行如下配置:

def initialize(context):
    g.security = "600570.SS"
    set_universe(g.security)
    
    # 核心配置:防止重启导致策略状态重置
    set_parameters(
        not_restart_trade="1",            # 交易时间段若服务器重启,不自动重新拉起本交易(避免重复委托)
        server_restart_not_do_before="1"  # 若服务器重启导致重拉交易,一个交易日内不再重复执行 before_trading_start 函数
    )

参数说明:

  • not_restart_trade="1":在交易时间段(默认 09:00-11:30、13:00-15:30)避免重复执行,防止在 initializebefore_trading_start 中因重启而重复调用委托接口,造成重复下单。
  • server_restart_not_do_before="1":确保一个交易日内 before_trading_start 仅调用一次,避免重启时重复执行盘前逻辑。

方案二:利用 pickle 模块进行手动持久化与恢复

对于一些关键的策略状态(如持仓天数、仓龄、自定义信号等),最稳妥的方法是在本地保存 pickle 文件。在策略启动时尝试读取该文件,如果读取成功则直接恢复,避免在 initialize 中被硬编码覆盖。

示例代码:

import pickle
from collections import defaultdict

# 获取研究根目录路径
NOTEBOOK_PATH = get_research_path()

def initialize(context):
    # 1. 尝试从本地 pickle 文件恢复全局变量
    try:
        with open(NOTEBOOK_PATH + 'hold_days.pkl', 'rb') as f:
            g.hold_days = pickle.load(f)
        log.info("成功恢复持久化变量 hold_days")
    # 2. 如果文件不存在(首次启动),则进行初始化
    except Exception as e:
        log.info("未找到持久化文件,初始化变量 hold_days")
        g.hold_days = defaultdict(list)
        
    g.security = '600570.SS'
    set_universe(g.security)

def handle_data(context, data):
    # 策略交易逻辑...
    if g.security not in list(context.portfolio.positions.keys()) and g.security not in g.hold_days:
        order(g.security, 100)
        g.hold_days[g.security] = 1
        
    # 3. 每次关键变量改变后,将其写入本地文件进行持久化
    with open(NOTEBOOK_PATH + 'hold_days.pkl', 'wb') as f:
        pickle.dump(g.hold_days, f, -1)

⚠️ 实盘注意事项

  1. 私有变量不保存:全局变量 g 中以双下划线 __ 开头的变量(如 g.__my_private_var)为私有变量,系统在自动持久化时不会保存它们。如果不希望某些变量被系统持久化覆盖,可以将其命名为私有变量。
  2. 不可序列化对象:涉及到 I/O 操作的对象(如打开的文件、数据库连接、实例化的复杂类对象等)无法被 pickle 序列化,不能直接存入 g 对象中。这类对象应在 initialize 中使用私有变量(__ 开头)进行初始化。