问题描述
解决方案
在 QMT 的 Python API 中,可以通过 ContextInfo 对象提供的两个内置布尔型函数来判断这两个状态。这两个函数通常在 handlebar(ContextInfo) 函数中使用。
1. 判断是否为新 K 线的第一个 tick
使用函数:ContextInfo.is_new_bar()
- 含义:当某根 K 线的第一个 tick 数据到来(或者回测时进入新的一根 K 线)时,该函数返回
True,否则返回False。 - 用途:常用于在每一根 K 线开始时重置某些变量、计算开盘价逻辑或确保某个逻辑在每根 K 线只执行一次。
2. 判断当前是否为实时行情的最后一根 K 线
使用函数:ContextInfo.is_last_bar()
- 含义:判断当前运行到的 K 线是否为整个数据序列的最后一根 K 线。返回
True表示是最后一根,False表示是历史 K 线。 - 用途:QMT 在启动策略时会先回放历史 K 线。为了避免在回放历史数据时重复触发实盘交易信号,通常需要判断
if ContextInfo.is_last_bar():,确保策略逻辑只在最新的实时行情中执行下单操作。
代码示例
以下是一个完整的策略示例,展示了如何结合使用这两个函数:
# -*- coding: gbk -*-
def init(ContextInfo):
# 设置股票池,这里以浦发银行为例
ContextInfo.set_universe(['600000.SH'])
print("策略初始化完成")
def handlebar(ContextInfo):
# 获取当前 K 线索引
bar_pos = ContextInfo.barpos
# 1. 判断是否是最后一根 K 线(通常用于区分历史回测阶段和实时行情阶段)
if ContextInfo.is_last_bar():
# 这里是实时行情(或回测数据的最后一根)
# 2. 判断是否是这根 K 线的第一个 tick(新 K 线生成)
if ContextInfo.is_new_bar():
# 获取当前时间
timetag = ContextInfo.get_bar_timetag(bar_pos)
import datetime
date_time = datetime.datetime.fromtimestamp(timetag / 1000).strftime('%Y-%m-%d %H:%M:%S')
print(f"检测到新 K 线生成!当前时间: {date_time}, K线索引: {bar_pos}")
print("可以在此处执行每根 K 线初始化逻辑,例如重置计数器等。")
# 以下逻辑在最后一根 K 线的每个 tick 都会执行
# print(f"实时行情 tick 刷新中... barpos: {bar_pos}")
else:
# 这里是历史 K 线回放阶段
pass
总结
| 判断目标 | API 函数 | 返回值 | 典型应用场景 |
|---|---|---|---|
| 新 K 线首个 Tick | ContextInfo.is_new_bar() |
bool |
每日/每分钟初始化、开盘抢单、防止信号重复计算。 |
| 最新 K 线 | ContextInfo.is_last_bar() |
bool |
区分历史回放与实盘、确保只对最新行情下单、实盘风控检查。 |
Q&A
Q: is_new_bar() 在回测模式下和实盘模式下表现一样吗?
A: 逻辑上是一致的。在回测模式下,每当 handlebar 推进到下一根历史 K 线时,is_new_bar() 也会返回 True。在实盘模式下,只有当最新的行情数据切分出新的时间周期(例如从 10:00 变为 10:01 的第一笔数据),它才会返回 True。
Q: 如果我在 is_last_bar() 为 False 时下单会怎样?
A: 如果在 is_last_bar() 为 False 时调用交易函数(如 passorder),意味着你在对历史数据进行“交易”。在回测模式下,这是正常的逻辑,用于生成回测报告。但在实盘模式下(点击“运行”),如果不加此判断,策略启动瞬间会快速回放历史数据,导致历史信号在当前时刻集中触发,可能造成严重的误下单。因此,实盘策略务必加上 if ContextInfo.is_last_bar(): 判断。
Q: is_new_bar() 可以用来控制一根 K 线只交易一次吗?
A: 可以。将交易逻辑放在 if ContextInfo.is_new_bar(): 代码块内,可以确保该逻辑在当前 K 线周期内只触发一次(即在 K 线刚生成时)。不过更严谨的做法通常是配合全局变量记录状态,或者使用 do_order 配合 quickTrade=1 参数在 K 线结束时确认信号。