问题描述
在使用 downloadhistorydata 或 downloadhistorydata2 下载历史行情后,经常发生获取不到数据的情况。具体的说,1d、1m、5m 可以正常获取,但再往上如 30m、1h 就很难获取了,哪怕在 downloadhistorydata 和 getmarketdata 之间等待 1 分钟,并且反复下载页不行。不知是什么问题?downloadhistorydata2 的 callback 显示也是下载成功的。
解决方案
在使用 miniQMT (xtquant) 获取历史行情时,遇到 1m、5m、1d 正常,但 30m、1h 获取不到(即使 callback 显示成功)是一个非常典型的现象。这通常与 QMT 底层的数据存储和本地 K 线合成机制有关。
问题原因分析
- 底层数据源与本地合成机制:
QMT 服务器端通常只存储基础周期的数据(如tick、1m、1d)。对于5m、15m、30m、1h等更大周期的分钟线,QMT 客户端通常是通过底层的1m数据在本地实时合成的。当你调用download_history_data下载30m数据时,底层实际上需要依赖对应时间段的1m数据来进行聚合。 - 基础数据缺失:
如果本地没有该时间段完整的1m数据,即使下载30m的请求发送成功且回调返回成功,本地也无法正确合成出30m的 K 线。因此,随后的get_market_data就会返回空数据。 - 周期参数字符串不规范:
确保传入的周期参数严格符合 API 规范(如'30m'、'1h',注意小写)。
解决方案
要稳定获取 30m 或 1h 的数据,最核心的解决办法是:先确保本地有充足的 1m 基础数据。
步骤 1:先下载 1m 数据,再获取 30m/1h 数据
在请求 30m 或 1h 数据之前,先显式地下载同一时间段的 1m 数据。这样 QMT 底层引擎就能利用这些 1m 数据成功合成大周期 K 线。
from xtquant import xtdata
import time
stock_code = '000001.SZ'
start_time = '20230101'
end_time = '20231001'
# 1. 先下载基础的 1m 数据,确保本地有合成大周期的原材料
print("开始下载 1m 基础数据...")
xtdata.download_history_data(stock_code, period='1m', start_time=start_time, end_time=end_time)
# 2. (可选) 下载 30m 数据触发本地合成
print("开始下载 30m 数据...")
xtdata.download_history_data(stock_code, period='30m', start_time=start_time, end_time=end_time)
# 等待底层合成与落盘
time.sleep(2)
# 3. 获取 30m 数据
data_30m = xtdata.get_market_data(
field_list=['open', 'high', 'low', 'close', 'volume'],
stock_list=[stock_code],
period='30m',
start_time=start_time,
end_time=end_time,
count=-1
)
print("获取到的 30m 数据:")
print(data_30m)
步骤 2:使用 get_market_data_ex 替代 get_market_data
get_market_data_ex 返回的数据结构(Dict 嵌套 DataFrame)在处理多周期和缺失值时通常比老版本的 get_market_data 更稳定,建议优先使用:
data_1h = xtdata.get_market_data_ex(
field_list=[],
stock_list=[stock_code],
period='1h',
start_time=start_time,
end_time=end_time
)
print(data_1h[stock_code])
总结建议
- 黄金法则:凡是遇到非基础周期(如 15m、30m、1h)获取不到的情况,一律先下载对应时间段的
1m数据。 - 检查 QMT 客户端状态:miniQMT 依赖于后台运行的 QMT 终端。请确保 QMT 终端网络连接正常,且没有处于“极简模式”(极简模式可能会限制历史数据的下载和合成)。