问题描述
代码如下:
先 download 数据,文档说它是同步返回的,
随后获取得到的却是空数据。
比如 30m 是空的,但可能 1m 或 1d 是有数据的
这个情况是哪里出问题了?
解决方案
在 QMT (或 xtquant) 平台中,遇到获取某个特定周期(如 30m)行情数据为空,而其他周期(如 1d 或 1m)有数据的情况,最根本的原因通常是:本地没有该特定周期的历史数据。
QMT 平台的历史数据获取机制是强依赖本地数据的。不同周期的数据在本地是独立存储的,下载了日线(1d)或1分钟线(1m)数据,并不会自动在本地生成30分钟线(30m)数据。
以下是详细的排查步骤和正确的代码写法:
1. 核心排查:手动补充对应周期的本地数据
在运行策略或调用 API 获取历史数据之前,必须确保本地已经下载了对应周期的数据。
操作步骤:
- 打开 QMT 客户端。
- 找到并点击菜单栏的 “数据管理”(或“操作” -> “数据管理”)。
- 选择 “补充数据”。
- 在弹出的窗口中,选择你需要获取数据的市场和品种。
- 关键一步:在“周期”选项中,务必勾选上 30分钟线(30m)。
- 设置好需要补充的时间范围,点击下载。等待下载完成后,再次运行你的代码。
2. 代码层面的正确写法
在 QMT Python API 中,推荐使用 ContextInfo.get_market_data_ex 来获取行情数据。这个接口支持更丰富的数据结构(返回 pandas DataFrame),并且可以通过 subscribe=True 参数在实盘/模拟时订阅数据。
正确的获取 30m 数据的代码示例:
#coding:gbk
def init(ContextInfo):
# 设置股票池
ContextInfo.set_universe(['000300.SH'])
def handlebar(ContextInfo):
# 确保只在最后一根 K 线执行,避免历史回测时重复打印
if not ContextInfo.is_last_bar():
return
# 获取 30m 周期数据
# 注意:period 参数必须严格匹配文档,30分钟线为 '30m'
data = ContextInfo.get_market_data_ex(
fields=['open', 'high', 'low', 'close', 'volume'],
stock_code=['000300.SH'],
period='30m',
start_time='20230101', # 可以指定开始时间,为空则视为最早
end_time='', # 为空视为最新
count=100, # 获取最近100条
dividend_type='none', # 复权方式:'none', 'front', 'back' 等
fill_data=True,
subscribe=True # 开启订阅
)
# 检查是否获取到数据
if '000300.SH' in data and not data['000300.SH'].empty:
print("成功获取 30m 数据:")
print(data['000300.SH'].tail()) # 打印最后几条数据
else:
print("获取 30m 数据为空,请检查本地是否已下载该周期数据!")
3. 其他可能导致数据为空的原因
如果确认已经在客户端下载了 30m 数据,但代码返回依然为空,请检查以下几点:
period参数拼写错误:QMT 中 30 分钟线的标准传参是'30m'(小写 m),不要写成'30M'或'30min'。- 时间范围设置不当:如果你设置了
start_time和end_time,请确保该时间段内该品种确实有交易数据。时间格式通常为'YYYYMMDD'或'YYYYMMDDHHMMSS'。 - 合约代码格式错误:QMT 的合约代码必须带后缀,例如平安银行是
'000001.SZ',而不是'000001'。 - 回测时间限制:如果你是在“回测”模式下运行,获取的数据范围会受到策略编辑器中“回测参数 -> 开始时间/结束时间”的限制。
总结:遇到特定周期数据为空,99% 的情况是因为客户端没有补充该周期的历史数据。请先前往“数据管理”下载 30m 数据,然后再使用 get_market_data_ex 进行调用。