问题描述
查看 QMT 常见问题链接:常见问题 | 迅投知识库
发现有这样的说明:
订阅:指向行情服务器订阅指定品种行情, 共有四种周期(分笔 1 分钟 5 分钟 日线),可以订阅当日数据,当天以前的需要用 down_history_data 下. 订阅有最大数量限制(例如:假设最大数量限制为 300 个,则可以单独订阅日线 300 个,若同时订阅日线和五分钟 则各 150 个),如需订阅超过 300 个限额,可以在页面右上角,选购行情 vip 服务。对应 python 接口为 subscribe_quote 在新窗口打开 和 get_market_data_ex(subscribe=True,)在新窗口打开 其中,使用 get_market_data 或 get_market_data_ex(subscribe=True,) 时客户端会自动订阅传入的品种,不需要额外调用 subscibe_quote,但这种方式订阅的品种没有订阅号,无法手动反订阅,只能通过停止策略释放可订阅数。
但实际使用的时候碰到了问题,在 miniQMT 中,运行以下命令出错:
xtdata.get_market_data_ex(subscribe=True,), subscribe 参数无效
另外,如果不先用 xtdata.subscribe_quote 先行订阅数据,get_market_data_ex 就取不到实时行情数据。
请教:
第一,subscribe 参数 是否取消了?
第二,是否 get_market_data_ex 不能获取实时行情,一定需要先用 xtdata.subscribe_quote 订阅数据,才能用 get_market_data_ex 获取?
解决方案
你好!你遇到的问题主要是由于内置 QMT (ContextInfo) 与 独立版 miniQMT (xtdata) 两个不同运行环境下的 API 差异造成的。官方知识库中的说明主要针对的是内置 QMT 环境,而在 miniQMT 中,接口的设计有所不同。
以下是对你两个问题的详细解答:
第一:subscribe 参数是否取消了?
并没有取消,而是运行环境不同导致参数不适用。
-
在内置 QMT 环境中(使用
ContextInfo):
根据 QMT API 文档,ContextInfo.get_market_data_ex确实包含subscribe参数(默认为True)。在这个环境下,调用该函数会自动订阅传入的品种,不需要额外调用subscribe_quote。正如你看到的文档说明,这种方式没有订阅号,只能通过停止策略来释放订阅数。 -
在 miniQMT 环境中(使用
xtdata):
xtdata.get_market_data_ex接口没有subscribe这个参数。xtdata的设计逻辑是将“数据订阅”和“数据获取”严格分离。因此,当你在 miniQMT 中传入subscribe=True时,Python 会报错提示参数无效。
第二:是否 get_market_data_ex 不能获取实时行情,一定需要先用 subscribe_quote 订阅?
是的,在 miniQMT (xtdata) 中,必须先显式订阅。
在 miniQMT 环境下,获取实时行情的标准流程如下:
-
第一步:订阅数据
必须先使用xtdata.subscribe_quote向行情服务器发起订阅请求。只有订阅后,本地的 miniQMT 终端才会开始接收并更新该品种的实时 Tick 或 K 线数据。 -
第二步:获取数据
订阅成功后,你可以通过两种方式获取实时数据:- 主动拉取: 使用
xtdata.get_market_data_ex去读取本地已经更新的最新行情缓存。 - 被动推送(推荐): 在
subscribe_quote中传入callback回调函数,当有新行情到来时,系统会自动触发回调并推送最新数据。
- 主动拉取: 使用
总结与代码示例对比
为了让你更清晰地理解,以下是两种环境下的正确写法:
1. 内置 QMT 环境(策略编辑器内运行):
def handlebar(ContextInfo):
# 直接获取并自动订阅,无需 subscribe_quote
data = ContextInfo.get_market_data_ex(
['open', 'high', 'low', 'close'],
['000300.SH'],
period='1d',
subscribe=True # 这里有效
)
print(data)
2. miniQMT 环境(外部 Python 运行 xtdata):
from xtquant import xtdata
import time
# 1. 必须先订阅行情
xtdata.subscribe_quote('000300.SH', period='1d', count=-1)
# 等待数据接收(实际应用中建议使用回调函数)
time.sleep(1)
# 2. 再主动获取本地缓存的最新数据(注意:没有 subscribe 参数)
data = xtdata.get_market_data_ex(
field_list=['open', 'high', 'low', 'close'],
stock_list=['000300.SH'],
period='1d'
)
print(data)
建议: 在使用 miniQMT 开发实盘策略时,强烈建议使用 xtdata.subscribe_quote 配合 callback 回调函数的方式来处理实时行情,这样不仅能保证数据的实时性,还能有效降低主动轮询带来的性能消耗。