问题描述
我先调用了xtdata.download_history_data2(stock_list, '1d', end_time=today, callback=lambda data: print(data),
incrementally=None)
然后再调用xtdata.get_market_data_ex([], stocks, period='1d', count=11)
但是获取的数据却没有最新的数据,这是为什么呢?
或者大家都是怎么获取最新的数据的呢?
解决方案
为什么 download_history_data2 表现为异步?
在 QMT 的独立 Python API (xtquant.xtdata) 中,download_history_data2 的设计初衷是为了支持大数据量的高效下载。当你传入了 callback 参数时(如你代码中的 callback=lambda data: print(data)),该函数会自动切换为异步非阻塞模式。
它的执行逻辑是:向 QMT 客户端发送下载请求后立即返回,并在后台持续下载数据。每当有一批数据下载完成时,就会触发你传入的 callback 函数。因此,当你紧接着调用 xtdata.get_market_data_ex 时,后台的数据下载尚未完成,本地缓存中还没有最新的数据,导致你获取到的仍然是旧数据。
如何正确获取最新数据?
针对你的需求,以下是几种获取最新数据的标准做法:
方法一:使用同步阻塞下载(推荐用于盘前初始化)
如果你希望代码在数据完全下载完毕后再继续执行,请使用 xtdata.download_history_data(注意函数名没有 2),或者在调用 download_history_data2 时不要传入 callback 参数。同步阻塞模式会卡住主线程,直到数据全部下载到本地。
from xtquant import xtdata
# 1. 同步阻塞下载,代码会在这里等待直到下载完成
xtdata.download_history_data(stock_list, period='1d', start_time='', end_time=today)
# 2. 下载完成后,再从本地读取,此时就能拿到最新数据
data = xtdata.get_market_data_ex([], stock_list, period='1d', count=11)
print(data)
方法二:在 QMT 内置策略中使用自动订阅(内置环境推荐)
如果你是在 QMT 客户端内部编写策略(使用 ContextInfo),不需要手动调用下载接口。直接使用 ContextInfo.get_market_data_ex 并开启 subscribe=True,平台会自动处理数据的补充、订阅和本地缓存更新。
def handlebar(ContextInfo):
# 开启 subscribe=True,平台会自动补充并订阅最新数据
data = ContextInfo.get_market_data_ex(
['open', 'high', 'low', 'close'],
['000300.SH'],
period='1d',
count=11,
subscribe=True
)
print(data)
方法三:盘中获取最新实时数据(实盘推荐)
如果是为了在盘中获取最新的实时切片数据或 Tick 数据,不要频繁调用历史数据下载接口,这会带来极大的网络和磁盘开销。正确的做法是使用订阅机制或快照接口:
- 获取全量最新快照:使用
xtdata.get_full_tick(stock_list)可以瞬间获取指定股票列表的最新盘口和最新价。 - 实时行情订阅:使用
xtdata.subscribe_quote订阅所需股票,当有最新行情时,通过回调函数实时处理。
总结:
历史数据下载接口(download_history_data)主要用于策略启动前的数据初始化或回测数据补充。在盘中运行阶段,获取最新数据应依赖订阅机制 (subscribe) 或实时快照接口 (get_full_tick),这样既能保证数据的绝对实时性,又能避免异步下载带来的时序错乱问题。