问题描述
文档中 download_financial_data2(stock_list, table_list=[], start_time='', end_time='', callback=None)的示例callback 如下:
def on_progress(data):
print(data)
# {'finished': 1, 'total': 50, 'stockcode': '000001.SZ', 'message': ''}
测试实际输出:
{'total': 2, 'finished': 1}
{'total': 2, 'finished': 2}
目前callback的data参数中缺少'stockcode', 'message',期望实际传入callback方法的参数与文档一致
xquant版本已更新至最新版:xtquant_240329
解决方案
问题解析
在 QMT 的 xtquant 库(如您提到的 xtquant_240329 版本)中,download_financial_data2 接口的底层实现进行了优化和调整。为了提高批量下载的效率和减少回调带来的性能开销,最新版本的回调参数 data 结构被简化为仅包含整体进度的 {'total': 2, 'finished': 1},而移除了单只股票级别的 stockcode 和 message 字段。
官方文档中的示例 {'finished': 1, 'total': 50, 'stockcode': '000001.SZ', 'message': ''} 属于早期版本的遗留说明,尚未及时同步更新。
解决方案与替代方案
既然当前版本的回调无法直接获取当前正在下载的 stockcode,我们可以通过以下几种方式来满足您的业务需求:
1. 兼容当前回调结构
在编写回调函数时,建议使用 dict.get() 方法来安全地获取参数,避免因缺少键值而导致程序报错:
def on_progress(data):
total = data.get('total', 0)
finished = data.get('finished', 0)
stockcode = data.get('stockcode', '未知代码') # 兼容新旧版本
message = data.get('message', '')
print(f"下载进度: {finished}/{total}")
2. 分批下载以精确控制进度
如果您必须知道具体哪只股票下载完成或失败,可以将批量下载拆分为单只股票的循环下载(注意:这会降低整体下载速度,请根据实际情况权衡):
stock_list = ['000001.SZ', '600000.SH']
for stock in stock_list:
print(f"开始下载: {stock}")
# 每次只下载一只股票
xtdata.download_financial_data2([stock], table_list=['利润表'], start_time='20200101', end_time='20231231')
print(f"{stock} 下载完成")
3. 下载后进行数据完整性校验
通常下载财务数据的最终目的是使用。您可以在整体下载完成后,调用 ContextInfo.get_financial_data() 或 xtdata.get_financial_data() 来检查所需数据是否已经成功落到本地:
# 批量下载
xtdata.download_financial_data2(stock_list, table_list=['利润表'])
# 校验数据
for stock in stock_list:
data = xtdata.get_financial_data(stock_list=[stock], table_list=['利润表'])
if data.empty:
print(f"{stock} 财务数据缺失或下载失败")
else:
print(f"{stock} 数据就绪")
总结
建议您在实际开发中,以实际输出的 {'total': 2, 'finished': 1} 为准来做进度条展示。对于文档与实际不符的问题,通常会在后续的 xtquant 版本更新中修复文档描述。在量化策略开发中,采用**“批量下载 + 盘后校验”**的模式是更为稳健的做法。