🚀 AI 一键生成 qmt 策略代码

qmt 平台 get_history_data 与 get_market_data_ex 计算均线回测结果差距很大的原因是什么?

qmt | 发布时间: 2026/5/27
以下内容由 EasyQuant 生成。

问题描述

get_history_data与get_market_data_ex计算出来的均线回测结果差距很大是什么原因

get_history_data 与 get_market_data_ex 计算出来的均线回测结果差距很大是什么原因?

解决方案

在 qmt 平台中,使用 get_history_dataget_market_data_ex 计算均线回测结果出现较大差异,通常是由以下几个关键原因导致的:

1. 复权方式(Dividend Type)设置不同

这是导致历史数据计算(如均线)差异最常见的原因。

  • get_history_data:默认参数 dividend_type = 0(不复权)。如果在调用时没有显式指定复权方式,获取的将是不复权数据。不复权数据在股票发生分红派息或送转股时会出现价格跳空,导致均线计算严重失真。
  • get_market_data_ex:默认参数 dividend_type = 'follow'(跟随主图复权方式)。如果主图设置了前复权(通常回测推荐使用前复权),那么获取的数据就是复权后的数据。
    解决方法:确保两个函数调用时使用相同的复权方式,通常在回测中建议使用前复权(dividend_type=1'front')。

2. 停牌数据的处理(Skip Paused / Fill Data)

  • get_history_data:默认参数 skip_paused = True,即遇到停牌日会自动用停牌前最后一个交易日的价格进行填充。
  • get_market_data_ex:虽然参数中有 fill_data=True,但文档标注“暂不可用”。这意味着它可能不会自动填充停牌数据,或者处理方式与 get_history_data 不同。
    影响:如果计算均线的周期内包含停牌日,填充与不填充会导致计算均线时使用的有效数据点不同,从而产生差异。

3. 数据获取的基准时间与长度(Count vs Start/End Time)

  • get_history_data(len, period, field):严格按照指定的长度 len 向前获取数据。它依赖于当前 K 线的位置(ContextInfo.barpos)。
  • get_market_data_ex:可以通过 start_timeend_timecount 灵活获取。如果在盘中或回测的特定时间点调用,且没有严格对齐时间戳,获取的数据切片可能与 get_history_data 不完全一致。

4. 数据结构与对齐方式

  • get_history_data:返回的是一个字典,值为 list,且 list 中第 0 位为最早的价格,第 1 位为次早价格。如果直接对 list 求平均,需要注意索引顺序。
  • get_market_data_ex:返回的是 pandas.DataFrame,index 为时间序列。使用 pandas 的 rolling().mean() 计算均线时,处理的是时间序列对齐的数据。

总结与建议

为了消除差异,建议在策略中统一使用 get_market_data_ex(或 get_market_data 的替代方案),因为它返回的 DataFrame 更适合进行向量化计算(如均线),并且复权设置更直观。如果必须对比,请检查以下代码:

# 确保复权方式一致(例如都使用前复权)
# get_history_data 方式 (1: 向前复权)
his_data = ContextInfo.get_history_data(20, '1d', 'close', 1)

# get_market_data_ex 方式 ('front': 前复权)
df_data = ContextInfo.get_market_data_ex(['close'], [stock_code], period='1d', count=20, dividend_type='front')

仔细核对两者在同一时间点返回的原始价格序列是否一致,通常统一复权方式后,差异即可消除。