🚀 AI 一键生成 qmt 策略代码

如何通过 QMT 的 `subscribe_quote` API 订阅多只股票的实时行情?

qmt | 发布时间: 2025/11/26
以下内容由 EasyQuant 生成。

问题描述

如何实时获取多只股票的行情更新,而不仅仅是主图品种的?

解决方案

在 QMT 中,默认的 handlebar(ContextInfo) 函数是由主图品种(即你在界面上选择的那个品种)的行情驱动的。如果主图品种没有成交(例如停牌或冷门股),或者你想在其他股票有行情变动时立即触发逻辑,仅依靠 handlebar 是不够的。

要实现实时获取多只股票的行情更新,最标准且高效的方法是使用 ContextInfo.subscribe_quote() 接口配合回调函数

核心方案:使用 subscribe_quote 进行订阅

该接口允许你订阅任意数量股票的行情(通常是 Tick 分笔数据)。当这些股票有新的行情推送时,系统会立即调用你指定的回调函数,而不需要等待主图的 handlebar 刷新。

代码实现示例

以下是一个完整的策略代码示例,展示了如何订阅多只股票的 Tick 数据并在回调函数中处理:

# -*- coding: gbk -*-

def init(ContextInfo):
    """
    初始化函数:在这里进行行情订阅
    """
    # 1. 定义需要订阅的股票列表
    # 注意:实盘中建议不要一次性订阅过多(如几千只),以免阻塞回调处理
    target_stocks = ['600000.SH', '000001.SZ', '600519.SH']
    
    # 2. 遍历列表进行订阅
    # 参数说明:
    # stock_code: 股票代码
    # period: 'tick' (分笔数据), '1m' (1分钟线) 等。实时监控通常用 'tick'
    # dividend_type: 'none' (不复权)
    # callback: 数据推送时触发的函数名
    for stock in target_stocks:
        ContextInfo.subscribe_quote(stock, 'tick', 'none', on_quote_update)
    
    print(f"已完成订阅: {target_stocks}")

def on_quote_update(datas):
    """
    行情推送回调函数
    当订阅的股票有新行情时,此函数会被自动调用
    参数 datas: 字典格式 {code: dataframe}
    """
    # 遍历推送过来的数据(通常一次推送一只或多只)
    for stock_code, df in datas.items():
        # df 是一个 pandas DataFrame,包含该股票的行情数据
        if not df.empty:
            # 获取最新的一行数据
            last_row = df.iloc[-1]
            
            # 提取需要的字段,例如最新价、时间、成交量
            last_price = last_row['lastPrice']
            timetag = last_row['time'] # 时间戳
            
            # 打印输出或执行交易逻辑
            print(f"【行情更新】{stock_code} | 时间: {timetag} | 最新价: {last_price}")
            
            # 示例:可以在这里直接写简单的监控逻辑
            # if last_price > 100:
            #     print(f"{stock_code} 价格突破 100元!")

def handlebar(ContextInfo):
    """
    主图K线驱动函数
    如果使用了 subscribe_quote,这里的逻辑可以留空,
    或者只处理与主图品种相关的逻辑。
    """
    pass

关键点解析

  1. ContextInfo.subscribe_quote:

    • 这是实现非主图驱动的核心。
    • period='tick': 设置为 'tick' 可以获得最高频率的更新(分笔成交)。
    • callback=on_quote_update: 必须传入一个函数对象(不要加括号),当数据到达时,QMT 底层会把数据打包传给这个函数。
  2. 回调函数 (on_quote_update):

    • 入参 datas 是一个字典,Key 是股票代码,Value 是包含行情数据的 pandas.DataFrame
    • 这个函数是在独立于 handlebar 的事件循环中运行的,因此反应速度最快。
  3. 数据字段:

    • 返回的 DataFrame 包含标准的 Tick 字段,如 lastPrice (最新价), amount (成交额), volume (成交量), askPrice (卖价列表), bidPrice (买价列表) 等。

另一种补充方式:主动查询 (Polling)

如果你不需要毫秒级的“推送”,也可以在 handlebar 中使用 ContextInfo.get_full_tick() 主动批量查询。但这种方式受限于主图的刷新频率。

# -*- coding: gbk -*-
def handlebar(ContextInfo):
    # 获取当前时刻多只股票的最新 Tick 快照
    stock_list = ['600000.SH', '000001.SZ']
    tick_data = ContextInfo.get_full_tick(stock_list)
    
    for stock, data in tick_data.items():
        print(f"{stock} 最新价: {data['lastPrice']}")

注意:这种方式只有在主图品种产生新 K 线或 Tick 时才会执行,实时性不如 subscribe_quote

总结

要实现实时监控多只股票,请务必使用 ContextInfo.subscribe_quote 配合回调函数。这是 QMT 提供的标准事件驱动模式。


Q&A

Q: subscribe_quote 订阅的数量有限制吗?
A: 理论上没有硬性限制,但受限于计算机性能和网络带宽。如果订阅全市场几千只股票的 Tick 数据,回调函数处理不过来会导致卡顿或延迟。建议只订阅策略关注的股票池(例如几百只以内)。

Q: 回调函数里可以直接下单吗?
A: 可以。在 on_quote_update 里判断出信号后,可以直接调用 passorderorder_shares 等交易函数进行下单。这是实现高频或网格交易的常用做法。

Q: 为什么我的回调函数没有打印数据?
A: 请检查:1. 是否在 init 中正确调用了 subscribe_quote;2. 当前是否为交易时间;3. 策略运行模式是否为“实盘”或“模拟交易”(回测模式下,Tick 级别的回调可能受限于回测数据的精度和机制,通常回测主要依靠 handlebar)。