问题描述
/
解决方案
在 ptrade 量化交易平台中,如果您遇到 before_trading_start 和 handle_data 同时运行或重复执行,导致策略逻辑混乱(例如变量被重置、重复委托下单等),这通常是因为服务器环境重启拉起交易所导致的。
问题原因分析
当券商服务器在交易时间段发生重启并恢复交易时,ptrade 框架默认会先执行策略的 initialize 函数,然后再执行 before_trading_start 函数。如果此时正处于盘中交易时间,handle_data 也会被触发。这会导致:
- 在
initialize或before_trading_start中初始化的非持久化全局变量被重置,破坏了handle_data正在依赖的逻辑状态。 - 如果在
before_trading_start中有委托下单逻辑,可能会造成重复委托。
解决方案
为了避免这种情况,ptrade 提供了 set_parameters 接口,允许您在 initialize 中配置策略在服务器重启时的行为。
您需要设置以下两个参数:
not_restart_trade: 交易时间段若服务器重启,是否自动执行重新拉起本交易。设置为"1"表示不执行。server_restart_not_do_before: 若服务器重启导致重拉交易,是否重复执行before_trading_start函数。设置为"1"表示不执行(即一个交易日内仅调用一次)。
代码示例
在您的策略 initialize 函数中添加如下配置:
def initialize(context):
g.security = "600570.SS"
set_universe(g.security)
# 关键配置:防止服务器重启导致的逻辑混乱
# 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")
def before_trading_start(context, data):
# 盘前逻辑,配置后每天只执行一次
log.info("执行盘前初始化逻辑")
g.daily_buy_flag = False
def handle_data(context, data):
# 盘中交易逻辑
if not g.daily_buy_flag:
order(g.security, 100)
g.daily_buy_flag = True
额外建议
- 持久化变量:对于跨日或跨重启需要保持状态的变量,务必使用
pickle模块进行持久化保存,或者利用框架自带的g对象持久化机制(注意以__开头的私有变量不会被持久化)。 - 避免在盘前下单:尽量不要在
initialize和before_trading_start中调用order系列委托接口,将交易逻辑集中在handle_data、tick_data或定时任务中。