问题描述
使用 qmt 下载 ohlc 数据,策略设置主图代码是 sa2609,策略中同时下载其他品种的 ohlc 数据常常不对,出现多个分钟线数据相同的情况,如何处理解决
解决方案
在 QMT 平台中,当策略的主图品种(如 sa2609)与你试图获取数据的其他品种不一致时,如果出现多个分钟线数据相同(即数据不更新、呈现一条直线)的情况,通常是因为未订阅非主图品种的实时行情或本地历史数据缺失导致的。
QMT 默认只会主动推送和更新主图品种的行情数据。对于非主图品种,如果没有显式订阅,系统可能会返回本地缓存的旧数据,或者使用前一个有效价格进行填充(停牌填充机制),从而导致你看到的 OHLC 数据重复。
解决方案
要解决这个问题,可以通过以下几种方式处理:
1. 使用 get_market_data_ex 并开启订阅(推荐)
QMT 提供了 ContextInfo.get_market_data_ex 接口,该接口包含一个 subscribe 参数。将其设置为 True,可以在获取数据的同时自动订阅该品种的行情,确保后续数据能够实时更新。
#encoding:gbk
def init(ContextInfo):
# 初始化时可以设置股票池
ContextInfo.set_universe(['rb2310.SF', 'hc2310.SF'])
def handlebar(ContextInfo):
# 确保只在最后一根K线(实时行情)时处理,避免历史回测时频繁打印
if not ContextInfo.is_last_bar():
return
# 获取非主图品种的分钟线数据,务必设置 subscribe=True
data = ContextInfo.get_market_data_ex(
fields=['open', 'high', 'low', 'close'],
stock_code=['rb2310.SF', 'hc2310.SF'],
period='1m',
count=5,
subscribe=True # 关键参数:开启数据订阅
)
print(data)
2. 在 init 中显式订阅行情
如果你使用的是旧版的 get_market_data 或者 get_history_data,你需要在 init 函数中使用 ContextInfo.subscribe_quote 显式订阅你需要获取数据的品种。
#encoding:gbk
def init(ContextInfo):
# 显式订阅其他品种的 1分钟线 行情
ContextInfo.subscribe_quote('rb2310.SF', period='1m', dividend_type='none')
ContextInfo.subscribe_quote('hc2310.SF', period='1m', dividend_type='none')
def handlebar(ContextInfo):
if not ContextInfo.is_last_bar():
return
# 此时获取的数据将会是实时更新的
df = ContextInfo.get_market_data(
['open', 'high', 'low', 'close'],
stock_code=['rb2310.SF', 'hc2310.SF'],
period='1m',
count=5
)
print(df)
3. 检查并补充本地数据
如果是在回测模式下出现数据重复,或者实盘刚启动时历史数据不对,是因为本地缺少该品种的分钟线历史数据。QMT 的回测和历史数据获取依赖于本地数据。
操作步骤:
- 在 QMT 客户端界面,点击顶部菜单栏的 “数据管理”。
- 选择 “补充数据”。
- 勾选你需要用到的所有品种(如
sa2609以及其他相关合约)。 - 勾选对应的周期(如
1分钟线)。 - 设定好时间范围,点击下载补充。
总结
- 实盘/模拟运行:务必使用
subscribe=True或subscribe_quote订阅非主图品种的行情。 - 历史回测:务必在“数据管理”中提前下载好所有涉及品种对应周期的历史数据。
- 停牌填充:注意
get_market_data中的skip_paused参数,如果品种无交易(如夜盘未开盘),默认会用前收盘价填充,也会导致数据看起来重复。