🚀 AI 一键生成 joinquant 策略代码

为什么 JoinQuant 的 run_weekly 函数会在非指定的星期几触发?

joinquant | 发布时间: 2026/5/21
以下内容由 EasyQuant 生成。

问题描述

关于run_weekly定时函数运行问题

run_weekly(weekly_adjustment,2,'10:00')
def weekly_adjustment(context):
log.info("每周二调仓")
2024-09-19 10:00:00 - INFO - 每周二调仓
以上是部分代码和日志输出,函数定义的是每周二调仓,但通过回测策略查看日志,发现2024-09-19这天也有触发这个函数,但实际上这天是周四,所以理应不触发。so有哪位大佬知道这是什么问题吗?

解决方案

您好!出现这个问题的原因在于对 run_weekly 函数中 weekday 参数的理解存在偏差。

原因分析

在 JoinQuant 的 API 中,run_weekly(func, weekday, time, ...)weekday 参数代表的是**“每周的第几个交易日”**,而不是自然日历中的“星期几”。

我们来看一下 2024 年 9 月中旬的日历和 A 股休市安排:

  • 2024 年 9 月 16 日(周一)和 9 月 17 日(周二)是中秋节假期,A 股休市。
  • 因此,该周的第一个交易日是 9 月 18 日(周三)。
  • 该周的第二个交易日是 9 月 19 日(周四)。

您的代码 run_weekly(weekly_adjustment, 2, '10:00') 意思是:在每周的第二个交易日的 10:00 执行。所以,在 2024-09-19(周四)触发是完全符合 API 设计逻辑的。

此外,API 文档中还提到:“开始策略的那一周第一个交易日是从策略开始的那一天计算的。” 这也可能导致在策略刚启动的第一周,触发的自然日与您预期的不同。

解决方案

如果您希望策略严格在每周二执行(如果周二休市则跳过,或者顺延),可以通过以下两种方式实现:

方法一:在回调函数中增加星期几的判断(推荐)

您可以将定时任务设置为每天运行,或者每周的某一天运行,然后在函数内部使用 Python 的 datetime 模块判断当天是否为星期二(isoweekday() == 2)。

def initialize(context):
    # 每天 10:00 运行
    run_daily(weekly_adjustment, time='10:00')

def weekly_adjustment(context):
    # isoweekday() 返回 1-7 代表周一到周日
    if context.current_dt.isoweekday() != 2:
        # 如果不是周二,直接返回,不执行调仓逻辑
        return
    
    log.info("今天是周二,执行调仓")
    # 下面写您的调仓逻辑

方法二:结合 run_weekly 和 isoweekday

如果您希望尽量减少函数的调用次数,可以保留 run_weekly,但为了防止节假日导致的错位,依然需要在函数内进行判断:

def initialize(context):
    # 尝试在每周的第2个交易日运行
    run_weekly(weekly_adjustment, 2, time='10:00')

def weekly_adjustment(context):
    if context.current_dt.isoweekday() != 2:
        log.info("本周第二个交易日不是周二,跳过调仓")
        return
        
    log.info("每周二调仓")

注意:方法二在遇到周一或周二休市的周时,会导致该周完全不调仓。如果您希望在周二休市时顺延到周三调仓,建议使用方法一,并自行编写顺延逻辑。

总结来说,量化回测中处理时间时,一定要区分**“交易日”“自然日”**的概念,JoinQuant 的 run_weeklyrun_monthly 默认都是基于“交易日”来计算的。