3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是完全正常的现象。
在 QMT(迅投/国信)量化平台中,subscribe_whole_quote(全量/全市场订阅)和 subscribe_quote(单票/指定标的订阅)在底层的数据处理机制上有着本质的区别。您所遇到的“全量订阅无法通过 get_market_data_ex 获取,而单票订阅可以”正是由这两种机制的设计初衷决定的。
subscribe_whole_quote(全量订阅)的内存推送机制全市场订阅通常涉及几千只股票的实时 Tick 数据。如果将这些高频、海量的数据实时写入本地硬盘,会造成极大的磁盘 I/O 瓶颈,导致系统卡顿甚至崩溃。因此,QMT 底层对全量订阅的设计是纯内存回调推送:
get_market_data_ex 读取:因为 get_market_data_ex 的底层逻辑是优先从本地数据库/缓存中读取数据,既然全量订阅没有落盘,该函数自然无法获取到最新数据。subscribe_quote(指定订阅)的落盘机制subscribe_quote 主要用于订阅少数指定的合约(如主图合约或特定的股票池)。
get_market_data_ex:当您调用 get_market_data_ex 时,系统能够从本地读取到刚刚通过 subscribe_quote 补充进来的最新数据。如果您需要处理全量行情数据,建议采用以下方式:
对于全量订阅,最标准的做法是直接在回调函数中接收并处理数据,而不是试图去本地读取。您可以将需要的数据存入 Python 的全局变量(如 dict)中供策略使用。
# 全量订阅回调处理示例逻辑
def on_whole_quote(datas):
# datas 通常是一个字典,包含了推送过来的最新行情
for stock_code, data in datas.items():
# 直接在内存中处理或更新您的全局状态
# 例如:ContextInfo.my_market_data[stock_code] = data
pass
subscribe_quote如果您的策略只需要关注特定的股票池(例如沪深300成分股,或者几十只自选股),强烈建议使用 subscribe_quote 遍历订阅这些股票,而不是使用全量订阅。这样既能保证数据自动落盘,又能完美兼容 get_market_data_ex。
def init(ContextInfo):
# 订阅特定股票池
stock_list = ['000300.SH', '600000.SH', '000001.SZ']
for code in stock_list:
ContextInfo.subscribe_quote(code, period='1d', dividend_type='none', callback=on_quote)
def on_quote(datas):
# 单票订阅的回调
print("收到行情推送:", datas)
def handlebar(ContextInfo):
# 此时可以通过 get_market_data_ex 获取到已订阅落盘的数据
data = ContextInfo.get_market_data_ex(
['close'], ['000300.SH'], period='1d'
)
print(data)
subscribe_whole_quote) = 内存回调,不落盘,适合高频/全市场扫描,需在回调中自行维护状态。subscribe_quote) = 自动落盘,适合特定股票池,完美兼容 get_market_data_ex。