问题描述
解决方案
在 JoinQuant 聚宽平台中,如果您希望在策略运行过程中取消之前通过 run_daily、run_weekly 或 run_monthly 设置的所有定时运行函数,可以使用 unschedule_all() 函数。
核心函数
unschedule_all()
- 作用:取消所有之前注册的定时运行任务。
- 参数:无。
- 返回值:None。
- 适用场景:通常用于
after_code_changed函数中。在模拟交易更新代码时,为了防止旧的定时任务和新的定时任务重复叠加,往往需要先清空旧任务,再重新注册新任务。
代码示例
以下示例展示了如何在模拟交易更新代码后(after_code_changed),清除旧的定时任务并重新设置新的任务:
# -*- coding: utf-8 -*-
def initialize(context):
# 策略初始化时设置一个定时任务
run_daily(func_old, time='10:00')
def func_old(context):
log.info("这是旧的定时任务")
def func_new(context):
log.info("这是新的定时任务")
# 模拟交易中,当点击“编译运行”更新代码后,会执行此函数
def after_code_changed(context):
# 1. 取消所有之前设置的定时任务(清除 func_old 的调度)
unschedule_all()
# 2. 重新设置新的定时任务
run_daily(func_new, time='14:00')
log.info("已重置所有定时任务")
注意事项
- 全量清除:
unschedule_all()会清除所有通过run_xxx系列函数注册的任务。如果您只想修改其中某一个,也必须先全部清除,然后将需要保留的任务和新任务一起重新注册。 - 不影响 handle_data:该函数只影响定时任务,不会影响
handle_data或handle_tick的运行机制。 - 执行时机:如果在
initialize中调用,通常没有意义(因为初始化时还没任务),它主要用于动态调整策略逻辑或模拟盘更新代码的场景。
Q&A
Q: unschedule_all() 会取消 before_trading_start 或 after_trading_end 吗?
A: 不会。before_trading_start 和 after_trading_end 是系统标准回调函数,不属于动态注册的定时任务,unschedule_all() 仅针对 run_daily、run_weekly 和 run_monthly 注册的函数生效。
Q: 如果我不调用 unschedule_all() 直接再次调用 run_daily 会怎样?
A: 每次调用 run_daily 等函数都会产生一个新的定时任务。如果您在 after_code_changed 中不先清除旧任务而直接添加新任务,旧的任务依然存在,会导致任务重复执行或执行多余的旧逻辑。
Q: 能否只取消特定的某一个定时任务?
A: 聚宽 API 目前仅提供 unschedule_all() 来取消所有任务,不支持通过 ID 或函数名取消特定的单个任务。必须采用“全部清除 -> 重新注册所需任务”的模式。