问题描述
比如,30 分钟 K 线,检测最后一个分笔到来的方法
解决方案
在 QMT 平台的 Python API 中,并没有直接提供一个名为 is_last_tick() 的方法来绝对精准地判断当前分笔是否是该 K 线的最后一个分笔。原因在于,在实时行情中,系统无法预知当前分笔之后、K 线结束之前是否还会产生新的分笔数据。
不过,针对您的需求(例如在 30 分钟 K 线结束时执行某些操作),可以通过以下几种替代方案来实现:
方案一:利用 QMT 默认的交易机制(推荐)
QMT 平台的模型是根据行情驱动的。在盘中,最后一根 K 线每变动一次(即每个 tick 到来),handlebar 函数就会被执行一次。QMT 默认的机制是:只有当这根 K 线确定走完(即下一根 K 线的第一个 tick 到来时),产生的信号才是有效信号,才会触发下单。
因此,如果您只是为了在 K 线走完时确认信号并下单,直接编写您的逻辑即可,QMT 底层会自动帮您处理“K线结束确认”的问题。
方案二:使用 ContextInfo.is_new_bar() 判断新 K 线开始
如果您需要在代码逻辑中明确知道上一根 K 线已经结束,可以使用 ContextInfo.is_new_bar() 方法。当某根 K 线的第一个 tick 数据到来时,该方法返回 True。这也就意味着上一根 K 线刚刚结束。
def handlebar(ContextInfo):
# 判断是否是实时行情的最后一根K线
if ContextInfo.is_last_bar():
# 判断是否是新的一根K线的第一个tick
if ContextInfo.is_new_bar():
print("新K线开始了,意味着上一根K线已经结束!")
# 在这里处理上一根K线结束后的逻辑
方案三:通过时间戳精确计算(适用于需要在 K 线结束前一瞬间操作)
如果您必须在当前 30 分钟 K 线结束前的最后一刻(例如 14:59:59)进行操作,可以通过获取当前 tick 的时间戳,并将其转换为时间字符串进行判断。
from datetime import datetime
def handlebar(ContextInfo):
# 只在实时行情的最后一根K线处理
if not ContextInfo.is_last_bar():
return
# 获取当前主图品种最新分笔对应的时间戳(毫秒)
tick_timetag = ContextInfo.get_tick_timetag()
if tick_timetag == 0:
return
# 将毫秒时间戳转换为 datetime 对象
# 注意:QMT 提供了一个内置函数 timetag_to_datetime(timetag, format)
# 这里我们将其转换为 HHMMSS 格式
time_str = ContextInfo.timetag_to_datetime(tick_timetag, '%H%M%S')
int_time = int(time_str)
# 假设是 30 分钟 K 线,结束时间点通常是 10:00, 10:30, 11:00, 11:30, 13:30, 14:00, 14:30, 15:00
# 我们可以判断当前时间是否在这些结束时间点的前几秒内(例如前 3 秒)
# 注意:这种方法依赖于市场在这些时间点有活跃的交易(有 tick 产生)
end_times = [95957, 102957, 105957, 112957, 132957, 135957, 142957, 145957]
for end_time in end_times:
# 判断当前 tick 时间是否在 K 线结束前的 3 秒内
if end_time <= int_time <= end_time + 3:
print(f"当前时间 {time_str},接近 30 分钟 K 线结束!")
# 执行您的逻辑,例如使用 do_order(ContextInfo) 提前发出信号
# do_order(ContextInfo)
break
总结
- 常规策略:直接写逻辑,QMT 默认在下一根 K 线第一个 tick 确认上一根 K 线的信号。
- 严格确认:使用
ContextInfo.is_new_bar()判断新 K 线产生,从而确认旧 K 线结束。 - 提前抢跑:使用
ContextInfo.get_tick_timetag()获取当前 tick 时间,判断是否接近 K 线理论结束时间。