🚀 AI 一键生成 qmt 策略代码

QMT 策略回测中如何正确处理分红送股等除权除息事件?

qmt | 发布时间: 2025/12/11
以下内容由 EasyQuant 生成。

问题描述

在策略回测时,怎样才能避免分红送股对价格数据造成的跳空影响?

解决方案

在 QMT 策略回测中,为了避免分红、送股等公司行为导致股价出现非市场因素的“跳空缺口”,从而影响策略信号的准确性,必须使用复权数据

通常推荐使用前复权(Forward Adjustment),因为它以当前价格为基准,向下调整历史价格,保持了最新的价格与实际盘面一致,非常适合策略回测和实盘信号判断。

在 QMT 中,可以通过以下两种方式来实现:

方法一:在策略编辑器界面设置(全局生效)

这是最简单的方法。在 QMT 客户端的策略编辑器中,无需修改代码,直接更改设置即可:

  1. 打开【策略编辑器】。
  2. 在右侧或下方的【基本信息】面板中找到 “复权方式” 选项。
  3. 将其设置为 “前复权”(或者“等比前复权”)。
  4. 设置后,策略中所有默认跟随主图的数据获取函数(如 dividend_type='follow')都会自动使用前复权数据。

方法二:在代码中指定复权参数(API 控制)

如果你需要在代码中精确控制获取的数据类型,或者混合使用不同复权方式的数据,可以在调用数据获取接口时显式指定 dividend_type 参数。

推荐使用 ContextInfo.get_market_data_ex 接口,因为它更高效且功能更全。

关键参数说明

  • dividend_type:
    • 'none': 不复权(原始价格,会有缺口)
    • 'front': 前复权(推荐用于回测)
    • 'back': 后复权
    • 'follow': 跟随主图/界面设置

代码示例

以下代码展示了如何在策略中强制获取“前复权”的历史数据,以消除分红影响:

# -*- coding: gbk -*-

def init(ContextInfo):
    # 设置股票池,例如平安银行
    ContextInfo.set_universe(['000001.SZ'])
    
    # 可以在init中打印提示
    print("策略初始化完成,准备获取前复权数据...")

def handlebar(ContextInfo):
    # 获取当前K线位置
    index = ContextInfo.barpos
    
    # 获取当前主图的股票代码
    stock_code = ContextInfo.stockcode + '.' + ContextInfo.market
    
    # 仅在最后一根K线或特定条件下打印,避免日志过多
    if ContextInfo.is_last_bar():
        # 【核心代码】使用 get_market_data_ex 获取前复权数据
        # dividend_type='front' 强制指定为前复权
        # count=10 获取最近10根K线
        data_map = ContextInfo.get_market_data_ex(
            fields=['open', 'high', 'low', 'close'], 
            stock_code=[stock_code], 
            period='1d', 
            start_time='', 
            end_time='', 
            count=10, 
            dividend_type='front',  # 这里指定 'front' 即可避免分红缺口
            fill_data=True, 
            subscribe=True
        )
        
        if stock_code in data_map:
            df = data_map[stock_code]
            print(f"股票 {stock_code} 的最近10日前复权数据:")
            print(df)
            
            # 示例:计算简单的均线,因为是复权价格,不会受分红跳空影响
            if len(df) >= 5:
                ma5 = df['close'].rolling(window=5).mean().iloc[-1]
                print(f"当前5日均线价格: {ma5}")

总结

  1. 界面设置:将策略属性中的“复权方式”改为“前复权”,这是最快捷的方式。
  2. 代码设置:在 get_market_data_exget_history_data 中将 dividend_type 参数设置为 'front' (或 1 对于旧版接口)。

通过以上设置,历史K线将变得平滑,技术指标(如均线、MACD)计算将基于调整后的价格,从而避免因分红造成的虚假交易信号。


Q&A

Q: 为什么回测通常推荐使用“前复权”而不是“后复权”?
A: 前复权是以当前最新价格为基准,调整过去的价格。这意味着图表上的最新价格与你实际看到的盘面价格一致,方便直观判断和实盘核对。后复权虽然也能消除缺口,但会导致当前价格变成一个很大的数字(如几千元),与实际交易价格不符,容易造成混淆。

Q: get_history_data 接口如何设置复权?
A: get_history_data 是较老的接口,它的 dividend_type 参数是数字类型。0 代表不复权,1 代表前复权,2 代表后复权。建议尽量使用 get_market_data_ex

Q: 如果我在界面设置了“前复权”,代码里写 dividend_type='none',以哪个为准?
A: 以代码为准。代码中的显式参数优先级高于界面设置。如果代码中写 dividend_type='follow',则会使用界面的设置。