🚀 AI 一键生成 joinquant 策略代码

为什么 JoinQuant 的 handle_data 不包含 11:30 和 15:00?如何获取这两分钟的 Bar 数据?

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

问题描述

请教get_bars问题

如果希望获取每分钟bar数据,在handle_date中使用get_bars获取,但由于handle_date并不包括11:30和15:00这两分钟,所以导致这两分钟无法获取bar数据。

问题一:请问为什么handle_date不包含11:30和15:00这两分钟呢?

问题二:该如何获取这两分钟的bar数据呢?

解决方案

您好!关于您在 JoinQuant 聚宽平台使用 handle_dataget_bars 时遇到的时间点触发问题,以下是详细的解答:

问题一:为什么 handle_data 不包含 11:30 和 15:00 这两分钟?

这与 JoinQuant 引擎的底层设计以及 A 股的交易时间划分有关。

根据 JoinQuant 的 API 文档说明:

按分钟回测/模拟,在每分钟的第一秒运行,每天执行 240 次,不包括 11:30 和 15:00 这两分钟,data 是上一分钟的分钟数据。

具体原因如下:

  1. K 线的定义(后对齐):聚宽的 K 线数据是后对齐的。例如,09:31 的 K 线,代表的是 09:30:00 到 09:30:59 这一分钟的交易数据。因此,每天的第一根分钟 K 线是 09:31,最后一根是 15:00。
  2. 触发机制handle_data 是在每分钟的开始触发的。每天的 240 次触发时间点分别是 09:3011:29(共 120 次),以及 13:0014:59(共 120 次)。
  3. 收盘时刻没有盘中触发:11:30 和 15:00 是中午和下午的收盘时刻。在 11:30:00 产生的是 11:29:00-11:29:59 的 K 线(标记为 11:30),此时盘面已经休息,引擎不会在 11:30 触发盘中回调。同理,15:00 是全天收盘,引擎会在收盘后执行 after_trading_end,而不会再触发 handle_data

简单来说,handle_data 是用来在交易时段内做决策的,而 11:30 和 15:00 已经是休市状态,因此不会触发。


问题二:该如何获取这两分钟的 bar 数据呢?

虽然 handle_data 不在这两分钟触发,但这两分钟的 K 线数据是真实存在的。您可以通过以下几种方式获取:

方法 1:在下一个交易时段的开始获取(推荐)

11:30 的 K 线可以在 13:00 触发时获取;15:00 的 K 线可以在收盘后的函数中获取。

def handle_data(context, data):
    # 当时间是 13:00 时,获取到的最新一根 1m K线就是 11:30 的
    if context.current_dt.strftime('%H:%M') == '13:00':
        bars = get_bars('000001.XSHE', count=1, unit='1m', fields=['date', 'close'])
        log.info("获取到 11:30 的数据: %s" % bars)

def after_trading_end(context):
    # 15:00 的数据在收盘后获取
    bars = get_bars('000001.XSHE', count=1, unit='1m', fields=['date', 'close'])
    log.info("获取到 15:00 的数据: %s" % bars)

方法 2:使用 run_daily 定时任务

如果您希望在特定的时间点准时处理,可以放弃 handle_data,改用 run_daily 来精确控制运行时间。

def initialize(context):
    # 盘中每分钟运行(等同于 handle_data)
    run_daily(my_handle, time='every_bar')
    # 专门针对 11:30 和 15:00 之后的时间点设置定时任务
    # 注意:11:30 和 15:00 刚收盘,建议稍微延后一点点获取,或者在收盘后函数中获取
    run_daily(get_1130_data, time='13:00') # 13:00 开盘时获取上午最后一分钟
    run_daily(get_1500_data, time='15:30') # 收盘后获取全天最后一分钟

def my_handle(context):
    # 正常的盘中逻辑
    pass

def get_1130_data(context):
    bars = get_bars('000001.XSHE', count=1, unit='1m', include_now=False)
    log.info("11:30 的 Bar: %s" % bars)

def get_1500_data(context):
    bars = get_bars('000001.XSHE', count=1, unit='1m', include_now=False)
    log.info("15:00 的 Bar: %s" % bars)

方法 3:直接拉取更长周期的 get_bars

如果您在盘中某个时刻需要过去一段时间的连续数据(包含 11:30),只要 count 足够大,get_bars 返回的数组中自然会包含 11:30 的数据。例如在 13:05 调用 get_bars(..., count=10, unit='1m'),返回的数据中就会包含 11:26 到 11:30,以及 13:01 到 13:05 的连续 K 线。

总结
11:30 和 15:00 的数据并没有丢失,只是 handle_data 的触发机制避开了休市时刻。利用 after_trading_end 或在下一个开盘时刻(13:00 和次日 09:30)调用 get_bars 即可完美获取。