🚀 AI 一键生成 qmt 策略代码

为什么QMT中get_history_data与get_market_data_ex计算的均线回测结果差距很大?

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

问题描述

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

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

解决方案

在 QMT 平台中,使用 get_history_dataget_market_data_ex 计算均线(MA)等技术指标时,如果发现回测结果差距很大,最核心的原因通常是:两个函数默认的复权方式(dividend_type)不同。

以下是详细的原因分析及解决方案:

1. 默认复权方式不同(核心原因)

股票在发生分红、送股等除权除息事件后,价格会出现跳空。如果不进行复权处理,直接计算均线会导致指标严重失真。

  • get_history_data 的默认复权方式是不复权
    根据 QMT API 文档,get_history_datadividend_type 参数默认值为 0(不复权)。
  • get_market_data_ex 的默认复权方式是跟随主图
    get_market_data_exdividend_type 参数默认值为 'follow'(跟随当前主图复权方式)。在进行策略回测时,我们通常会在策略基本信息中将主图设置为“前复权”。

结果差异:如果你在代码中没有显式指定复权参数,get_history_data 取到的是不复权数据,而 get_market_data_ex 取到的是前复权数据。用这两组不同的价格序列计算出来的均线自然会产生巨大的差异,进而导致买卖信号和回测收益完全不同。

2. 停牌数据的填充处理差异

  • get_history_data:参数 skip_paused 默认为 True,即遇到停牌日会自动用停牌前最后一个交易日的价格进行填充。
  • get_market_data_ex:参数 fill_data 默认为 True,但文档中特别标注了“暂不可用”。这可能导致在某些特定停牌场景下,两者返回的 K 线序列长度或数据对齐方式存在细微差别。

3. 数据获取的基准点不同

  • get_history_data:是基于当前运行到的 K 线(ContextInfo.barpos)往前取 len 根 K 线的数据。它严格依赖于当前主图的进度。
  • get_market_data_ex:可以通过 start_timeend_time 灵活指定时间段,或者通过 count 往前取值。如果时间参数设置不当,可能导致取到的数据区间与预期不符。

💡 解决方案:显式指定相同的复权方式

为了保证计算结果的一致性,强烈建议在调用这两个接口时,显式地传入相同的复权参数(推荐使用前复权)

正确的使用示例:

def handlebar(ContextInfo):
    # 假设我们要计算 000001.SZ 的 5 日均线
    stock = '000001.SZ'
    
    # 1. 使用 get_history_data,显式指定 dividend_type = 1 (前复权)
    # 注意:get_history_data 只能获取 ContextInfo.set_universe() 中设置的股票数据
    his_dict = ContextInfo.get_history_data(5, '1d', 'close', dividend_type=1)
    if stock in his_dict and len(his_dict[stock]) == 5:
        ma5_history = sum(his_dict[stock]) / 5.0
        
    # 2. 使用 get_market_data_ex,显式指定 dividend_type = 'front' (前复权)
    df_ex = ContextInfo.get_market_data_ex(
        fields=['close'], 
        stock_code=[stock], 
        period='1d', 
        count=5, 
        dividend_type='front'
    )
    if stock in df_ex and not df_ex[stock].empty and len(df_ex[stock]) == 5:
        ma5_ex = df_ex[stock]['close'].mean()
        
    # 此时 ma5_history 和 ma5_ex 的计算结果应该是一致的

总结:在量化回测中,处理股票数据时务必时刻关注复权问题。统一使用前复权(dividend_type=1'front')可以有效消除因接口默认值不同带来的回测误差。