问题描述
get_market_data不能获取1分钟K线吗?
需要使用1分钟K线,只有get_market_data_ex才可以?
在回测时,如何将get_market_data_ex实现像get_market_data数据推送模式一样,每根K线推送一组新数据?
回测时get_market_data跟get_market_data_ex运行逻辑不一样吗
解决方案
针对您在 QMT 平台回测时获取 1 分钟 K 线数据的疑问,以下是详细的解答:
1. get_market_data 不能获取 1 分钟 K 线吗?只有 get_market_data_ex 才可以?
并不是。 get_market_data 同样可以获取 1 分钟 K 线数据(通过设置参数 period='1m')。
但是,根据 QMT 官方 API 文档的说明,get_market_data 接口已不建议使用。官方强烈建议开发者使用升级版的 ContextInfo.get_market_data_ex。get_market_data_ex 在数据返回结构(返回标准的 Dict[code, pandas.DataFrame])、参数控制以及运行效率上都做了优化,因此在编写新策略时,请务必使用 get_market_data_ex。
2. 回测时 get_market_data 跟 get_market_data_ex 运行逻辑不一样吗?
在回测的时间基准逻辑上,两者是一致的。当你在 handlebar 函数中调用这两个接口,并且不指定具体的 start_time 和 end_time 时,它们都会以当前 handlebar 运行到的 K 线时间点作为基准,向前获取指定 count 数量的数据。
主要的区别在于返回的数据结构和参数定义:
get_market_data返回的数据结构会根据传入参数的数量(单股/多股、单时间点/多时间点)发生变化(可能是数值、Series、DataFrame 或 Panel),处理起来非常容易出错。get_market_data_ex返回的数据结构非常稳定,始终是一个字典,键为股票代码,值为pandas.DataFrame,极大地简化了数据处理逻辑。
3. 如何将 get_market_data_ex 实现每根 K 线推送一组新数据的模式?
QMT 的策略运行机制是行情驱动(逐 K 线运行)。在回测时,系统会从历史数据的第一根 K 线开始,依次调用 handlebar(ContextInfo) 函数。
要实现“每根 K 线推送一组新数据”(即滑动窗口模式),你只需要在 handlebar 中调用 get_market_data_ex,不传入 start_time 和 end_time(或设为空字符串 ''),仅指定 count 参数即可。
随着回测的推进,每次进入 handlebar,当前时间点都在向后移动,get_market_data_ex 取到的 count 根 K 线数据自然也就是随着时间推移而更新的最新数据。
代码示例:在回测中逐 K 线获取最新的 1 分钟数据
#coding:gbk
def init(ContextInfo):
# 设置股票池
ContextInfo.set_universe(['000001.SZ'])
# 假设主图周期设置为 1m,或者在回测参数中设置
def handlebar(ContextInfo):
# 确保在历史 K 线走完时才触发交易逻辑(可选,视策略而定)
# if not ContextInfo.is_last_bar():
# return
# 获取当前股票池
stock_list = ContextInfo.get_universe()
# 使用 get_market_data_ex 获取 1 分钟 K 线数据
# start_time 和 end_time 留空,count=5 表示获取截止当前时间点的最新 5 根 1 分钟 K 线
data = ContextInfo.get_market_data_ex(
fields=['open', 'high', 'low', 'close', 'volume'],
stock_code=stock_list,
period='1m',
start_time='',
end_time='',
count=5,
dividend_type='front', # 前复权
subscribe=True
)
# 遍历获取到的数据
for code in stock_list:
if code in data and not data[code].empty:
df = data[code]
# 打印当前 K 线时间点和最新收盘价
# df 的 index 是时间字符串
current_time = df.index[-1]
latest_close = df['close'].iloc[-1]
print(f"时间: {current_time}, 代码: {code}, 最新1分钟收盘价: {latest_close}")
# 在这里编写你的交易逻辑...
总结
- 放弃使用
get_market_data,全面改用get_market_data_ex。 - 在
handlebar中调用get_market_data_ex,利用count参数而不写死时间,即可完美实现随 K 线推进的动态数据获取(推送模式)。