问题描述
用上述代码获取数据得到的结果是空值,有几个问题请教大佬:
1、使用这个函数获取数据,是实时从服务器去取吗?还是获取本地的数据?
2、集合竞价期间用这个函数获取 tick 数据是否可以?
3、为什么我取不到数据,是什么原因呢?
解决方案
针对您在使用 QMT 平台 get_market_data_ex 函数时遇到的数据获取为空的问题,以下是详细的解答和排查指南:
1. 数据是实时从服务器取还是本地取?
get_market_data_ex 函数的数据获取机制取决于参数设置以及您请求的数据类型(历史数据 vs 实时数据):
- 历史数据:QMT 默认优先从本地读取。如果您请求的是过去的 K 线或 Tick 数据,必须先在 QMT 客户端的“数据管理”中下载补充对应品种和周期的数据。如果本地没有数据,函数将返回空值。
- 实时数据:该函数有一个
subscribe参数(默认为True)。当subscribe=True时,函数会向服务器订阅该品种的实时行情,并在后续有新行情时更新数据;如果设置为False,则只读取本地已有的数据,不会向服务器发起订阅。
2. 集合竞价期间用这个函数获取 tick 数据是否可以?
可以的。
在 A 股市场的集合竞价期间(9:15 - 9:25),交易所会定时推送行情快照(Tick 数据)。只要您的 QMT 客户端行情连接正常,使用 period='tick' 是可以获取到集合竞价期间的 Tick 数据的。需要注意的是,集合竞价期间的 Tick 推送频率与盘中连续竞价不同(通常是 3 秒一笔),且 9:25 会推送开盘集合竞价的最终结果。
3. 为什么取不到数据?常见原因排查
如果您调用该函数返回空值,通常是由以下几个原因导致的,请逐一排查:
原因一:未补充本地历史数据(最常见)
如果您在回测或盘中请求历史数据,但没有在 QMT 客户端下载数据,就会返回空值。
- 解决方法:打开 QMT 客户端 -> 菜单栏 -> 数据管理 -> 补充数据,选择您需要的市场、品种和周期(如日线、1分钟线、Tick等)进行下载。
原因二:股票代码格式不正确
QMT 的 API 对股票代码格式有严格要求,必须包含市场后缀。
- 错误写法:
'000001','600000' - 正确写法:
'000001.SZ','600000.SH'
原因三:时间参数格式错误
start_time 和 end_time 参数必须是特定格式的字符串。
- 正确格式:
'YYYYMMDD'(如'20231001')或'YYYYMMDDHHMMSS'(如'20231001093000')。如果格式错误或时间范围设置不合理(例如start_time大于end_time),将返回空值。
原因四:周期参数(period)不支持
请检查传入的 period 参数是否在官方支持的范围内。
- 支持的周期:
'tick','1m','5m','15m','1d'等。如果拼写错误(如写成'1D'大写),可能会导致解析失败。
原因五:在非最后一根 Bar 频繁调用(实盘/模拟)
在实盘运行模式下,如果您的策略是逐 K 线运行的,建议在 ContextInfo.is_last_bar() 为 True 时才去获取最新的实时数据,否则在历史 Bar 回放阶段可能会因为时间戳不匹配或数据未准备好而获取异常。
正确的代码示例
def handlebar(ContextInfo):
# 确保只在最新的一根 K 线上获取实时数据
if not ContextInfo.is_last_bar():
return
# 获取沪深300指数的日线数据,确保代码带后缀,且 subscribe=True
data = ContextInfo.get_market_data_ex(
fields=['open', 'high', 'low', 'close'],
stock_code=['000300.SH'],
period='1d',
start_time='',
end_time='',
count=10, # 获取最近10条
dividend_type='front',
subscribe=True
)
print(data)
总结建议:先检查代码后缀是否带 .SH/.SZ,然后去 QMT 客户端手动补充一下该品种的数据,最后检查时间参数格式。通常这三步能解决 90% 以上返回空值的问题。