一、关于handledata的执行周期
日志输出如下:
[2026\7\31 21.57.25] [INFO][59]: 当前触发时间:20260731 220000
[2026\7\31 21.57.25] [INFO][59]: 60分钟线 - 时间: 20260731 15.000000 开盘: 2989.00 收盘: 2987.00
[2026\7\31 21.57.25] [INFO][59]: 日线 - 时间: 20260731 0.000000 开盘: 2997.00 收盘: 2987.00
[2026\7\31 21.59.4] [INFO][59]: 当前触发时间:20260731 220000
[2026\7\31 21.59.4] [INFO][59]: 60分钟线 - 时间: 20260731 15.000000 开盘: 2989.00 收盘: 2987.00
[2026\7\31 21.59.4] [INFO][59]: 日线 - 时间: 20260731 0.000000 开盘: 2997.00 收盘: 2987.00
[2026\7\31 22.0.1] [INFO][59]: 当前触发时间:20260731 230000
[2026\7\31 22.0.1] [INFO][59]: 60分钟线 - 时间: 20260803 22.000000 开盘: 2991.00 收盘: 2972.00
[2026\7\31 22.0.1] [INFO][59]: 日线 - 时间: 20260731 0.000000 开盘: 2997.00 收盘: 2987.00
[2026\7\31 22.0.3] [INFO][59]: 当前触发时间:20260731 230000
[2026\7\31 22.0.3] [INFO][59]: 60分钟线 - 时间: 20260803 22.000000 开盘: 2991.00 收盘: 2972.00
[2026\7\31 22.0.3] [INFO][59]: 日线 - 时间: 20260731 0.000000 开盘: 2997.00 收盘: 2987.00
结论:
1.handledata按tick执行。
2.60m的按60m执行
查看极智回测显示的k线,(2989.00 2987.00),(2991.00 2972.00)就是rb2609的1小时k线的数据。
(开盘: 2997.00 收盘: 2987.00)就是日线的数据。
3.当前触发时间:20260731 220000后来显示23:00,因为context.dateTimeStamp() 返回的是触发本次 handle_data 执行的那个事件所对应的时间戳,本例中就是60m。
测试代码
import talib
def initialize(context):
context.contract = Symbol()
SetBarInterval(context.contract, 'M', 60, 'A')
SetBarInterval(context.contract, 'D', 1, 'A')
# 设置实盘运行
SetActual()
SetTriggerType(5)
def handle_data(context):
contract = context.contract
# ---------- 获取数据数组 ----------
open_240_arr = Open(contract, 'M', 60)
close_240_arr = Close(contract, 'M', 60)
open_D_arr = Open(contract, 'D', 1)
close_D_arr = Close(contract, 'D', 1)
# 检查数据长度是否至少为2(确保存在上一根K线)
if len(open_240_arr) < 2 or len(open_D_arr) < 2:
LogInfo("数据不足,240分钟线数量:%d,日线数量:%d" % (len(open_240_arr), len(open_D_arr)))
return
# ---------- 打印当前触发时间 ----------
ts = context.dateTimeStamp() #根据极智量化 API 手册(第 129 页),context.dateTimeStamp() 返回的是触发本次 handle_data 执行的那个事件所对应的时间戳。
ts_str = str(ts)
date_str = ts_str[:8]
time_str = ts_str[8:14]
LogInfo("当前触发时间:%s %s" % (date_str, time_str))
# ---------- 获取上一根240分钟K线的价格和时间 ----------
open_240 = open_240_arr[-2]
close_240 = close_240_arr[-2]
# 使用 HisBarsInfo 获取最近2根K线的详细信息,取索引 -2 为上一根
bars_240 = HisBarsInfo(contract, 'M', 60, 2)
if len(bars_240) >= 2:
prev_240 = bars_240[-2]
date_240 = prev_240['TradeDate'] # 整数日期,如 20260731
dt_240 = str(prev_240['DateTimeStamp']) # 字符串,如 "20260731113000000"
# 提取时间部分 HHMMSS
if len(dt_240) >= 14:
time_240_str = dt_240[8:14] # "113000"
time_240 = float(time_240_str[:2] + "." + time_240_str[2:4] + time_240_str[4:6]) # 转为 0.113000
else:
time_240 = 0.0
else:
date_240 = 0
time_240 = 0.0
LogInfo("60分钟线 - 时间: %d %.6f 开盘: %.2f 收盘: %.2f" % (date_240, time_240, open_240, close_240))
# ---------- 获取上一根日线的价格和时间 ----------
open_D = open_D_arr[-2]
close_D = close_D_arr[-2]
bars_D = HisBarsInfo(contract, 'D', 1, 2)
if len(bars_D) >= 2:
prev_D = bars_D[-2]
date_D = prev_D['TradeDate']
dt_D = str(prev_D['DateTimeStamp'])
if len(dt_D) >= 14:
time_D_str = dt_D[8:14]
time_D = float(time_D_str[:2] + "." + time_D_str[2:4] + time_D_str[4:6])
else:
time_D = 0.0
else:
date_D = 0
time_D = 0.0
LogInfo("日线 - 时间: %d %.6f 开盘: %.2f 收盘: %.2f" % (date_D, time_D, open_D, close_D))
存在的问题:handledata还是每一个tick触发一次。
原因:
极智量化的实盘运行机制如下:
在实盘中,SetTriggerType(5) 代表“K线数据变化触发”。
行情每来一个 Tick(分笔),当前这根 60 分钟 K 线的高开低收等数据就会实时更新(即“数据发生变化”)。
由于您没有设置发单方式,系统默认使用了“实时发单”模式(等同于 SetOrderWay(1))。在该模式下,每一个 Tick 的更新都会触发策略执行 handle_data。
解决方案:
现状:SetTriggerType(5) + 默认实时发单 = 每个 Tick 触发。
修正:SetTriggerType(5) + SetOrderWay(2) = 每根 K 线收盘后触发一次。
添加下面的代码:
# 添加这一行:设置 K 线稳定后发单(实盘下 K 线走完才触发一次)
SetOrderWay(2)

一个重要补充(99%的人会忽略的细节):
在 SetTriggerType(5) + SetOrderWay(1)(实时发单)模式下,虽然你设置了K线触发(5),但实际上,CTP柜台对单根K线内的多次触发是有限制的!
极智量化为了保证实盘稳定,在实时发单模式下,默认有一个 “同一根K线内,同方向的开仓信号只会执行一次” 的保护机制(除非你在界面设置里关闭了“每根K线同向开仓次数”的限制)。
所以在实盘写代码时,针对模式二,极智量化老手通常不会只写 if,而会加上一个 条件成立且当前Bar没有开过仓 的硬锁定,比如用 CurrentBar() 记录上一次开仓的Bar索引,防止信号反复触发。不过对于你现在的策略,沿用 SetOrderWay(2)(稳定发单)是最稳妥、最省心的选择。
一句话总结你的认知: 你总结的这两种情况,就是极智量化数据源的核心底层逻辑。放心按这个认知去写策略,绝对正确!
2.
SetTriggerType(5) + SetOrderWay(2)这个组合对我实盘也没有用啊。
如果收盘前产生信号,然后第2天k线推送的时候已经是4个小时之后了。
三、有的合约没有夜盘
LC2609(碳酸锂期货 2026 年 9 月合约)