问题描述
[市场数据订阅失败-func:subscribeWholeQuote, error:{ "error" : { "ErrorID" : 200005, "ErrorMsg" : "未找到处理函数" } }]
解决方案
报错原因分析
在QMT券商版中调用全推数据订阅接口(如 subscribeWholeQuote)时,遇到 ErrorID: 200005, ErrorMsg: "未找到处理函数" 的报错,通常由以下几个原因导致:
- 接口不支持或被阉割:
subscribeWholeQuote通常属于底层 C++ 接口或xtquant独立版 API。在 QMT 内置的 Python 策略编辑器中,官方推荐的行情订阅接口是ContextInfo.subscribe_quote。部分券商版 QMT 可能出于性能或合规考虑,在内置环境中屏蔽或未实现subscribeWholeQuote的底层映射。 - 缺少全推/Level2行情权限:全推数据(尤其是 Level2 快照或逐笔数据)通常需要向券商额外申请或付费开通。如果账号没有全推权限,服务端会拒绝请求并返回异常。
- 回调函数未正确传递:如果是在
xtquant(xtdata) 环境下调用xtdata.subscribe_whole_quote,必须确保正确绑定了回调函数,否则底层无法找到处理推送数据的函数指针。
解决方案
方案一:在 QMT 内置环境中使用 ContextInfo.subscribe_quote
如果您是在 QMT 客户端自带的策略编辑器中编写代码,请不要直接调用 subscribeWholeQuote,而是使用官方文档提供的 ContextInfo.subscribe_quote 接口。该接口支持单只或多只股票的行情订阅,并能触发回调。
正确代码示例:
#coding:gbk
def init(ContextInfo):
# 订阅沪深300ETF的日线行情,并绑定回调函数 on_quote
ContextInfo.sub_id = ContextInfo.subscribe_quote('510300.SH', period='1d', dividend_type='follow', callback=on_quote)
print(f"订阅成功,订阅号: {ContextInfo.sub_id}")
def on_quote(datas):
# 行情推送回调函数
print("收到行情推送:", datas)
def handlebar(ContextInfo):
pass
方案二:在 xtquant 独立环境中的正确调用方式
如果您使用的是独立版 xtquant 库,调用全推接口时需要确保回调函数正确注册。注意:xtdata.subscribe_whole_quote 订阅的是全市场数据,数据量极大,请确保您的网络和处理逻辑能够承受。
xtquant 调用示例:
from xtquant import xtdata
# 定义回调函数
def on_data(datas):
for stock_code, data in datas.items():
print(f"代码: {stock_code}, 最新价: {data.get('lastPrice')}")
# 订阅全市场行情(需确保有权限)
# 注意:部分券商版 xtdata 可能不支持全推,建议按需使用 subscribe_quote 订阅特定股票池
try:
xtdata.subscribe_whole_quote(code_list=['SH', 'SZ'], callback=on_data)
except Exception as e:
print(f"全推订阅失败,请检查权限或改用普通订阅: {e}")
方案三:确认券商行情权限
如果您的策略确实需要全市场所有股票的 Tick 或 Level2 数据:
- 请联系您的券商客户经理,确认您的资金账号是否开通了 QMT全推行情权限 或 Level2 增强版权限。
- 如果券商不支持全推,建议通过
ContextInfo.get_sector('000300.SH')等方式获取特定板块的成分股列表,然后使用for循环结合ContextInfo.subscribe_quote进行批量订阅(注意控制订阅数量,避免触发频率限制)。