问题描述
2026-05-14 17:12:54 [ INFO] src.market.feed.vendors.miniqmt.miniqmt_market: 准备完成: ['231974.SH'] 1m 数据下载 (miniqmt_market.py:602)
2026-05-14 17:12:54 [ INFO] src.market.feed.vendors.miniqmt.miniqmt_market: 已完成: 231974.SH [1m] (1/8) 数据下载 (miniqmt_market.py:609)
2026-05-14 17:12:54 [ INFO] src.market.feed.vendors.miniqmt.miniqmt_market: 已完成: 231974.SH [1m] (2/8) 数据下载 (miniqmt_market.py:609)
2026-05-14 17:12:54 [ INFO] src.market.feed.vendors.miniqmt.miniqmt_market: 已完成: 231974.SH [1m] (3/8) 数据下载 (miniqmt_market.py:609)
2026-05-14 17:12:54 [ INFO] src.market.feed.vendors.miniqmt.miniqmt_market: 已完成: 231974.SH [1m] (4/8) 数据下载 (miniqmt_market.py:609)
2026-05-14 17:12:54 [ INFO] src.market.feed.vendors.miniqmt.miniqmt_market: 已完成: 231974.SH [1m] (5/8) 数据下载 (miniqmt_market.py:609)
2026-05-14 17:12:54 [ INFO] src.market.feed.vendors.miniqmt.miniqmt_market: 已完成: 231974.SH [1m] (6/8) 数据下载 (miniqmt_market.py:609)
2026-05-14 17:12:55 [ INFO] src.market.feed.vendors.miniqmt.miniqmt_market: 已完成: 231974.SH [1m] (7/8) 数据下载 (miniqmt_market.py:609)
2026-05-14 17:12:55 [ INFO] src.market.feed.vendors.miniqmt.miniqmt_market: 已完成: 231974.SH [1m] (8/8) 数据下载 (miniqmt_market.py:609)
两支股票分成 16 次下载
{'finished': 1, 'total': 16, 'stockcode': '', 'message': '600031.SH'}
{'finished': 2, 'total': 16, 'stockcode': '', 'message': '600031.SH'}
{'finished': 3, 'total': 16, 'stockcode': '', 'message': '600031.SH'}
{'finished': 4, 'total': 16, 'stockcode': '', 'message': '600031.SH'}
{'finished': 5, 'total': 16, 'stockcode': '', 'message': '600031.SH'}
{'finished': 6, 'total': 16, 'stockcode': '', 'message': '600031.SH'}
{'finished': 7, 'total': 16, 'stockcode': '', 'message': '600031.SH'}
{'finished': 8, 'total': 16, 'stockcode': '', 'message': '600031.SH'}
{'finished': 9, 'total': 16, 'stockcode': '', 'message': '600111.SH'}
{'finished': 10, 'total': 16, 'stockcode': '', 'message': '600111.SH'}
{'finished': 11, 'total': 16, 'stockcode': '', 'message': '600111.SH'}
{'finished': 12, 'total': 16, 'stockcode': '', 'message': '600111.SH'}
{'finished': 13, 'total': 16, 'stockcode': '', 'message': '600111.SH'}
{'finished': 14, 'total': 16, 'stockcode': '', 'message': '600111.SH'}
{'finished': 15, 'total': 16, 'stockcode': '', 'message': '600111.SH'}
{'finished': 16, 'total': 16, 'stockcode': '', 'message': '600111.SH'}
现在 message 里只有股票代码,而 stockcode 里反而为空了?是逻辑错误,还是?
按正常的逻辑,分批下载也可以,但是有没有一个返回值告诉分批下载完成的提示。
解决方案
在 qmt 平台中使用 xtdata.download_history_data2 下载历史数据时,遇到分批下载和回调参数的问题,这是由底层数据请求机制决定的。以下是详细的解析:
1. 为什么会分批下载?
xtdata.download_history_data2 在请求大量数据(如一年的分钟线数据)时,为了避免单次请求数据量过大导致网络超时或内存溢出,底层会自动将请求拆分成多个批次(例如按月或按一定数量的 K 线拆分)。
- 单只股票 8 个批次:说明底层将一年的分钟数据拆分成了 8 个请求包。
- 两只股票 16 个批次:每只股票 8 个批次,总计 16 个批次。
这种分批逻辑是正常的,旨在提高数据下载的稳定性和成功率。
2. 回调参数 stockcode 为空,message 为股票代码?
在 download_history_data2 的回调函数中,返回的字典结构通常如下:
{'finished': 1, 'total': 16, 'stockcode': '', 'message': '600031.SH'}
message字段:在当前版本的 qmt 中,message字段通常用于传递当前正在处理或已完成的标的信息(即股票代码)。stockcode字段:在某些特定场景或旧版本中可能被使用,但在当前的分批下载回调中,它可能为空,而将代码放在了message中。
这不是逻辑错误,而是接口设计的现状。开发者在处理回调时,应直接从 message 字段中提取股票代码。
3. 如何判断分批下载完成?
要判断整个下载任务是否完成,可以通过回调字典中的 finished 和 total 字段来判断。
当 finished == total 时,表示所有批次的数据均已下载完成。
示例代码:
from xtquant import xtdata
def on_download_progress(data):
finished = data.get('finished', 0)
total = data.get('total', 0)
message = data.get('message', '')
print(f"下载进度: {finished}/{total}, 当前处理: {message}")
if finished == total:
print("所有数据下载完成!")
# 在这里执行下载完成后的逻辑
# 下载两只股票的前一年分钟数据
stock_list = ['600031.SH', '600111.SH']
period = '1m'
start_time = '20220101'
end_time = '20221231'
xtdata.download_history_data2(stock_list, period, start_time, end_time, callback=on_download_progress)
总结
- 分批下载 是底层为了稳定性自动进行的拆包处理。
- 回调参数 中,股票代码目前存放在
message字段中,stockcode为空是正常现象。 - 完成判断 依赖于回调数据中的
finished == total条件。