3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 QMT 平台的回测模式下,get_market_data 和 get_market_data_ex 的运行逻辑确实存在差异,主要体现在对时间基准的默认处理方式上。
get_market_data 的逻辑:
在回测模式下,当您使用 get_market_data 并指定 count 参数(且不指定具体的 start_time 和 end_time)时,系统会自动以当前回测进度所在的 K 线(即当前 Bar)作为基准时间,向前推算获取指定数量的 K 线数据。因此,它能实现随着回测进度“一天一天推送”的效果。
get_market_data_ex 的逻辑:
get_market_data_ex 是一个更底层、更通用的接口。根据官方文档,当 start_time 和 end_time 为空时,它默认 end_time 为最新时间(即本地数据的最新日期,通常是今天)。它不会自动跟随回测的当前进度。因此,在回测的每一个周期里,它都去取了本地最新的数据,导致您看到“全是一样的数据”。
要让 get_market_data_ex 在回测中实现和 get_market_data 一样的效果(跟随回测进度逐根 K 线获取),您需要动态地将当前回测 K 线的时间作为 end_time 传入。
您可以通过 ContextInfo.get_bar_timetag(ContextInfo.barpos) 获取当前 K 线的时间戳,将其转换为字符串格式后传给 end_time。
#coding:gbk
import time
def init(ContextInfo):
ContextInfo.set_universe(['603660.SH'])
def handlebar(ContextInfo):
# 获取当前回测进度所在的 K 线索引
bar_index = ContextInfo.barpos
# 获取当前 K 线的时间戳(毫秒)
timetag = ContextInfo.get_bar_timetag(bar_index)
# 将时间戳转换为 get_market_data_ex 需要的字符串格式 (YYYYMMDD)
# 注意:timetag_to_datetime 是 QMT 内置函数
current_date_str = timetag_to_datetime(timetag, '%Y%m%d')
fields = ['open', 'high', 'low', 'close', 'volume', 'amount']
periods = 5
stock_code = '603660.SH'
# 使用 get_market_data_ex,并动态传入 end_time
param_df = ContextInfo.get_market_data_ex(
fields=fields,
stock_code=[stock_code],
period='1d', # 明确指定周期
start_time='', # start_time 留空,由 count 决定向前取多少根
end_time=current_date_str, # 动态传入当前回测 K 线的时间
count=int(periods) + 1,
dividend_type='front',
fill_data=True,
subscribe=True
)
print(f"当前回测日期: {current_date_str}")
if stock_code in param_df:
print(param_df[stock_code])
get_market_data 在回测时具有“上下文感知”能力,会自动以当前 Bar 为截止时间。get_market_data_ex 是绝对时间查询,如果不传 end_time,永远返回最新数据。在回测中使用时,必须手动传入当前 Bar 的时间作为 end_time。