QMT 量化交易实战:一招教你极速获取当日行情数据(替代 get_market_data_ex)

23 阅读7分钟

本文针对 QMT 量化交易系统中当日数据获取速度慢、影响行情响应的痛点,详细讲解了subscribe_quote订阅机制的使用方法,通过盘中均线金叉的实战案例演示如何替代传统的get_market_data_ex函数实现毫秒级数据获取,并揭秘订阅机制的两大隐藏妙用,帮助量化交易者大幅提升策略执行效率。

一、QMT 本地数据模式的核心特点与痛点

QMT 作为国内主流的专业量化交易客户端,最显著的特征就是纯本地运行模式,所有行情数据必须预先下载至本地后才能被策略调用。这种设计是 QMT 区别于云端量化平台的核心优势,主要体现在三个方面:

  • 策略安全性更高:策略代码完全运行在用户本地设备,不会上传至任何第三方服务器,从根本上杜绝了核心交易逻辑泄露的风险
  • 数据响应更迅速:本地数据读写无需依赖公网传输,大幅降低了数据读取延迟,为高频交易提供基础保障
  • 策略研究功能更强大:支持本地海量历史数据的深度回测、因子挖掘和多维度分析,研究能力远超云端平台

但传统的当日数据获取方式存在明显短板:如果在盘中同步使用get_market_data_ex函数实时拉取当日数据,会占用大量网络带宽和系统 CPU 资源,直接导致行情刷新速度变慢。对于高频交易、套利交易等对毫秒级响应有要求的策略来说,这种延迟可能会造成严重的交易滑点,甚至直接错失最佳交易机会。

二、核心解决方案:subscribe_quote 订阅机制

为了解决上述问题,QMT 官方内置了行情订阅机制。其核心原理是:通过订阅函数提前向本地缓存服务器注册需要的行情数据,服务器会将对应标的、对应周期的实时数据持续推送至本地缓存;当策略需要使用数据时,可直接从本地缓存读取,无需每次都发起远程拉取请求。

2.1 核心函数对比说明

函数名功能适用场景速度表现
get_market_data_ex历史数据拉取盘后回测、历史数据分析盘中拉取当日数据速度慢,易卡顿
subscribe_quote当日行情订阅盘中实时交易、高频策略订阅后从本地缓存读取,毫秒级响应

关键结论:完成订阅后的get_market_data_ex调用速度会提升数十倍,完全可以替代原生的当日数据拉取逻辑,是 QMT 盘中获取当日数据的最优解

三、实战案例:盘中 1 分钟均线金叉策略

下面通过量化交易中最常用的盘中均线金叉策略,完整演示订阅机制的使用流程。本策略实现:当沪深 300ETF(510310.SH)的 5 分钟均线向上穿越 10 分钟均线时,自动触发买入指令,并通过全局开关变量避免重复下单。

3.1 完整可运行代码

# encoding:gbk
# 全局交易开关,控制是否允许执行买入操作
switch = 1

def init(C):
    # 定义行情回调函数:订阅后,行情更新时会自动触发
    def callback_func(data):
        global switch
        # 仅当开关开启时执行交易逻辑
        if switch == 1:
            # 从本地缓存获取当日1分钟K线数据(订阅后极速读取)
            datas = C.get_market_data_ex(
                fields=['close'],
                stock_list=['510310.SH'],
                period='1m',
                start_time='20250414',
                end_time='',
                count=10
            )
            # 提取收盘价列表用于计算均线
            close_list = datas['510310.SH']['close'].tolist()
            # 计算5周期和10周期移动平均线
            ma_5 = sum(close_list[-5:]) / 5
            ma_10 = sum(close_list[-10:]) / 10
            
            # 实时输出均线数值,便于监控策略运行状态
            print(f'ma_5: {ma_5}, ma_10: {ma_10}')
            
            # 均线金叉信号判断
            if ma_5 > ma_10:
                # 此处替换为你自己的下单函数(根据实盘需求调整参数)
                # C.passorder(...)
                switch = 0  # 关闭交易开关,避免重复买入
                print('【交易信号】ma_5上穿ma_10,触发买入指令')
    
    # 核心:订阅510310.SH的1分钟K线行情,绑定回调函数
    C.subscribe_quote(
        stock_list=['510310.SH'],
        period='1m',
        callback=callback_func
    )

def handlebar(C):
    # 订阅机制可完全替代handlebar的固定周期触发逻辑
    pass

3.2 代码执行步骤拆解

  1. 行情订阅:在策略初始化函数init中调用subscribe_quote,注册需要的标的和周期,并指定数据更新时的回调函数
  2. 缓存读取:每当有新的 1 分钟 K 线生成时,回调函数自动触发,通过get_market_data_ex直接从本地缓存读取最新的 10 根 K 线数据
  3. 指标计算:基于收盘价列表计算 5 周期和 10 周期移动平均线
  4. 信号执行:判断是否出现均线金叉,若满足条件则触发下单指令,并关闭全局开关防止重复交易

3.3 实际运行效果

代码运行后,控制台会实时输出均线数值,示例输出如下:

2025-04-15 14:09:51.506】ma_5: 3.6846, ma_10: 3.6849
2025-04-15 14:09:54.567】ma_5: 3.6846, ma_10: 3.6849
2025-04-15 14:09:57.613】ma_5: 3.6846, ma_10: 3.6849
...
【交易信号】ma_5上穿ma_10,触发买入指令

从监控结果可以看到,当 5 日均线(黑色)向上穿越 10 日均线(紫色)时,策略会在毫秒级时间内完成数据读取、指标计算和信号触发,全程无需人工干预。

四、订阅机制的两大隐藏妙用

很多量化新手只把订阅当作提升数据读取速度的工具,但实际上它还有两个非常实用的功能,能大幅优化你的策略性能和资源占用:

4.1 替代 handlebar,动态控制资源消耗

传统的 QMT 策略依赖handlebar函数按固定周期强制触发,无论是否有行情更新都会执行代码,容易造成不必要的 CPU 和流量浪费。而订阅机制只有在行情数据真正更新时才会触发回调函数,并且支持unsubscribe_quote反订阅操作,可以在策略不需要数据时主动取消订阅,动态释放系统资源。

4.2 支持 L2 逐笔数据推送,实现毫秒级响应

subscribe_quote函数原生支持 Level-2 行情数据的订阅,可以实现逐笔成交、逐笔委托的毫秒级推送。相比 Level-1 行情 3 秒一次的刷新频率,L2 行情的响应速度快了几十倍,对于高频交易、跨期套利、做市策略等对延迟要求极高的交易场景来说,是必不可少的核心功能。

五、总结与合规提示

5.1 核心要点总结

  1. QMT 的本地运行模式是其安全和速度的基础,但传统当日数据拉取方式存在明显延迟问题
  2. subscribe_quote订阅机制是 QMT 盘中获取当日数据的最优解,可完全替代get_market_data_ex的原生拉取逻辑
  3. 订阅机制不仅能提升数据读取速度,还能灵活控制资源占用,支持 L2 毫秒级行情推送

5.2 合规与风险提示

  1. 本文所提供的代码仅作学习交流使用,不构成任何投资建议,据此交易风险自担
  2. 量化交易存在较高市场风险,实盘交易前请务必进行充分的历史回测和模拟盘验证
  3. 开通 QMT 量化交易权限及 Level-2 行情需满足证券公司的相应资质要求