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

QMT实盘中 get_full_tick 返回价格数据滞后怎么办?

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

问题描述

get_full_tick函数,在某些时候返回的最新价格数据不准确

这种情况不常见,但的确会出现。今天就在实盘中出现,返回了不准确的数据,导致一支票卖飞掉了。

请看,第 1 个截图,是我量化系统在 11:01 份左右,通过 get_full_tick 获取的 002984 的最新价格为 15.13。但实际上,这个数据不准,可能是一个过期数据。请看截图 2,11:01 分左右的价格准确的应该是在 15.19 左右,而 15.13 这个价格,大概是 10:50 分左右的数据。然而,复盘一下,就是这 6 分钱之差,导致系统错误的执行了止损。然后,请看截图 3,真的不想说什么了....

ps:这不是个例。在差不多的时间段,数据不准确的情况在其它的票上也有发生,只是没造成损失罢了。

解决方案

在 QMT 实盘交易中,遇到 get_full_tick 返回滞后数据(如 11:01 获取到 10:50 的价格)导致错误止损,确实非常令人痛心。这种情况通常与本地行情缓存未及时更新未显式订阅行情有关。

为什么 get_full_tick 会返回不准确(滞后)的数据?

get_full_tick 函数的底层逻辑是直接读取 QMT 客户端本地缓存的最新分笔数据。如果出现数据滞后,通常有以下几个原因:

  1. 未显式订阅行情:如果该股票不在当前主图、未被加入自选股,或者策略中没有显式订阅该股票的行情,QMT 客户端可能不会高频向服务器请求该股票的最新 tick,导致本地缓存停留在历史某一时刻。
  2. 网络或行情服务器延迟:在极端行情或网络波动时,行情推送可能出现短暂卡顿。
  3. 主推机制限制:QMT 的 handlebar 默认由主图品种的 tick 驱动,如果主图品种有 tick 而目标股票没有 tick 更新,此时调用 get_full_tick 拿到的就是目标股票上一次的旧数据。

解决方案

为了避免这种“卖飞”的悲剧再次发生,建议对策略的数据获取方式进行以下优化:

1. 显式订阅目标股票的行情(强烈推荐)

在使用 get_full_tick 之前,确保已经使用 subscribe_quote 对目标股票进行了行情订阅。这样可以强制客户端保持该股票数据的实时更新。

def init(ContextInfo):
    # 显式订阅目标股票的 tick 行情
    ContextInfo.subscribe_quote('002984.SZ', period='tick', dividend_type='none', callback=on_quote)

def on_quote(datas):
    # 可以在回调中处理实时数据,或者仅用于保持数据活跃
    pass

def handlebar(ContextInfo):
    # 此时再调用 get_full_tick,数据滞后的概率会大幅降低
    tick_data = ContextInfo.get_full_tick(['002984.SZ'])
    if '002984.SZ' in tick_data:
        last_price = tick_data['002984.SZ']['lastPrice']
        print(f"最新价格: {last_price}")

2. 使用更可靠的 get_market_data_ex 替代

相比于 get_full_tickget_market_data_ex 提供了内置的订阅开关 subscribe=True,在获取数据的同时会自动处理订阅逻辑,数据可靠性更高。

def handlebar(ContextInfo):
    # 使用 get_market_data_ex 获取最新 1 分钟或 tick 数据,并开启 subscribe=True
    data = ContextInfo.get_market_data_ex(
        fields=['close'], 
        stock_code=['002984.SZ'], 
        period='1m', # 或者 'tick'
        count=1,
        subscribe=True # 关键参数:强制订阅最新数据
    )
    
    if '002984.SZ' in data and not data['002984.SZ'].empty:
        last_price = data['002984.SZ']['close'].iloc[-1]
        print(f"最新价格: {last_price}")

3. 增加数据有效性校验(防错机制)

在执行止损、止盈等关键交易动作前,增加对数据时间戳的校验。如果发现数据的时间戳与当前系统时间相差过大(例如超过 10 秒),则拒绝执行交易,等待下一个有效 tick。

import time

def handlebar(ContextInfo):
    # 获取当前系统时间戳(毫秒)
    current_time = int(time.time() * 1000)
    
    # 获取主图最新 tick 的时间戳作为参考
    tick_timetag = ContextInfo.get_tick_timetag()
    
    # 如果主图 tick 时间与当前时间脱节过大,说明整体行情可能卡顿,暂停交易
    if abs(current_time - tick_timetag) > 10000: # 10秒
        print("行情可能延迟,暂停关键交易动作")
        return
        
    # 继续执行获取价格和止损逻辑...

总结

实盘中绝对不能完全信任未经订阅的本地缓存数据。对于需要精确触发止损的策略,务必使用 subscribe_quoteget_market_data_ex(subscribe=True) 来确保数据的实时性,并在代码中加入时间戳校验的防错逻辑,以保护本金安全。