3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
针对您在国金 QMT 实盘中遇到的 gmdSubscribe timeout 问题,以下是详细的原因分析及解决方案:
在 QMT 的 Python API 中,get_market_data_ex 函数包含一个默认参数 subscribe=True。当您在盘中(如 10:30、14:45 等)调用该函数时,如果本地没有最新的数据,底层 C++ 引擎会向行情服务器发起实时订阅请求(即 gmdSubscribe)。
盘中特定时段(尤其是临近收盘的 14:45-15:00)行情服务器并发请求量极大,如果服务器响应稍慢,就会触发底层的 10 秒超时机制。由于这是底层 C++ 抛出的超时,Python 层无法捕获异常,从而导致 handlebar 被强制中断。
不需要。get_market_data_ex 默认自带订阅行为(subscribe=True)。正是这个默认的订阅行为在盘中引发了超时。
要避免触发 gmdSubscribe,您只需要在调用 get_market_data_ex 时,显式地将 subscribe 参数设置为 False。这样函数将只读取本地已有的数据,不会向服务器发起网络请求,从而彻底杜绝超时问题。
修改后的代码:
kline = ContextInfo.get_market_data_ex(
['close'],
[stock_code],
period='1d',
count=3,
subscribe=False # 关键参数:关闭实时订阅,仅读取本地数据
)
注:使用此方法的前提是,您在盘前(如 9:15)已经通过全市场查询或数据下载功能,将日线数据缓存到了本地。
除了关闭 subscribe 参数外,您还可以使用以下两种更轻量级的替代方法:
替代方法一:使用 get_history_data(推荐用于简单指标计算)
如果您只需要获取股票池内股票的历史数据,可以在 init 中设置股票池,然后在 handlebar 中直接获取。此函数直接读取本地内存数据,速度极快且不会超时。
def init(ContextInfo):
# 假设 stock_code 是您要查询的股票
ContextInfo.set_universe([stock_code])
def handlebar(ContextInfo):
# 获取股票池中所有股票最近3日的收盘价
his_dict = ContextInfo.get_history_data(3, '1d', 'close')
if stock_code in his_dict and len(his_dict[stock_code]) >= 3:
close_prices = his_dict[stock_code]
print(f"近3日收盘价: {close_prices}")
替代方法二:使用 get_local_data
直接读取本地硬盘/内存中的行情数据,不涉及任何网络请求。
def handlebar(ContextInfo):
# 获取本地最新的3条日线数据
local_data = ContextInfo.get_local_data(
stock_code=stock_code,
period='1d',
count=3
)
# local_data 返回的是 dict 结构,需自行解析 close 字段
对于实盘高频驱动的 handlebar(如 1 分钟或 tick 级别),强烈建议不要在其中发起任何带有网络请求的同步阻塞调用。请将 get_market_data_ex 的 subscribe 设为 False,或者改用 get_history_data,以确保策略运行的稳定性和流畅性。