3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 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)避免重复执行,防止在 initialize 或 before_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)
g 中以双下划线 __ 开头的变量(如 g.__my_private_var)为私有变量,系统在自动持久化时不会保存它们。如果不希望某些变量被系统持久化覆盖,可以将其命名为私有变量。pickle 序列化,不能直接存入 g 对象中。这类对象应在 initialize 中使用私有变量(__ 开头)进行初始化。