🚀 AI 一键生成 joinquant 策略代码
立即体验
👉 AI 生成代码 👈

JoinQuant平台模拟交易中run_daily函数触发延迟怎么办?

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

问题描述

run daily函数延迟问题

之前反映过的模拟交易信号延迟问题,经过打印系统时间确认,run daily函数在刚开始运行(函数计算前)就已经延迟。而后面的函数计算时间只花了0.02秒,所以延迟是由run daily引起的。
下图为两个模拟交易中设定为9:31的run daily的实际运行时间,之前有几天甚至延迟了3分钟以上,请问这个问题能解决吗?

解决方案

在JoinQuant(聚宽)平台的模拟交易中,遇到 run_daily 函数实际触发时间(物理时间)晚于设定时间(如9:31)的情况,是一个比较常见的现象。根据聚宽的底层架构和API文档,这种延迟主要由以下几个原因引起,并可以通过一些方法进行缓解。

一、 延迟产生的原因

  1. 服务器并发排队(主要原因)
    9:30、9:31、14:55、15:00 是绝大多数用户设定策略运行的绝对高峰期。在这些时间点,聚宽的服务器需要同时唤醒并执行海量的模拟盘进程。由于服务器计算资源有限,任务会被放入队列中排队执行。如果排在队列靠后,就会出现物理时间上的延迟(如您观察到的延迟几秒甚至几分钟)。

  2. 逻辑时间与物理时间的差异
    聚宽API文档中明确指出:“模拟盘有10s系统延迟, 日志中的时间并非实际时间而是逻辑时间”。策略内部的 context.current_dt 是严格对齐的逻辑时间(例如永远是 09:31:00),而您通过 datetime.datetime.now() 打印出的是服务器当前的物理时间。撮合引擎在处理分钟Bar限价单时,主要依赖逻辑时间,因此物理延迟对按Bar撮合的限价单影响相对可控,但对市价单的即时成交价格会有影响。

  3. 日级策略的特殊处理
    文档提到:“对于使用当日开盘价撮合的日级模拟盘...出于减少并发运行模拟盘数量的目的,我们会提前到9:27~9:30之间运行”。虽然这主要针对9:30的日频策略,但也侧面说明了平台为了应对并发所做的调度调整。

二、 解决方案与缓解建议

由于这是平台公共资源分配导致的物理延迟,作为普通用户无法直接修改底层调度,但可以通过以下策略层面的调整来最大程度规避或解决:

1. 错峰运行(最有效的方法)

尽量避开全网最拥堵的 9:309:31。如果您的策略逻辑允许,可以尝试将运行时间延后1-2分钟。

# 避开9:31的高峰,改为9:32运行
run_daily(my_trade_func, time='09:32')

2. 升级为 Tick 级别频率

如果您对交易信号的即时性要求极高(例如高频抢单、追涨停等),分钟级别的 run_daily 调度可能无法满足需求。建议将策略频率升级为 Tick级别,并使用 handle_tick 函数。

  • Tick级别策略是事件驱动的,每当交易所推送新的Tick数据时就会触发,实时性远高于分钟级别的定时任务。
  • 注意:Tick级别回测和模拟需要开通相应权限,且必须开启真实价格模式 set_option('use_real_price', True)

3. 使用盘口撮合模式

如果延迟导致您的市价单成交价格偏离预期,可以在模拟盘中开启盘口撮合模式,这样订单会根据真实的买卖盘口进行撮合,更贴近真实交易环境。

def initialize(context):
    # 开启盘口撮合模式(仅模拟盘有效)
    set_option('match_with_order_book', True)

4. 检查是否使用了耗时的初始化操作

虽然您提到核心计算只花了0.02秒,但请确保在 process_initialize 或全局作用域中没有进行耗时的网络请求或大规模数据加载,因为模拟盘每天重启恢复状态时会执行这些代码,可能会拖慢进程的启动速度。

总结

这种物理时间的延迟本质上是SaaS量化平台在早盘高峰期的并发瓶颈。错峰执行改用Tick驱动是目前最切实可行的解决方案。如果您的资金量较大且对延迟零容忍,通常需要考虑将策略迁移至本地化部署的实盘交易软件(如Ptrade/QMT)中运行。