🚀 AI 一键生成 qmt 策略代码
立即体验

QMT平台如何使用 get_divid_factors 接口获取复权因子并手动计算前复权价格?

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

问题描述

qmt 数据复权教程:利用 get_divid_factors 计算历史真实价格
QMT 怎么使用 get_divid_factors 接口获取股票的复权因子并手动计算前复权价格?

解决方案

QMT数据复权教程:利用 get_divid_factors 计算历史真实价格

在量化交易中,股票的除权除息(分红、送股、转增等)会导致股价出现非交易因素的断崖式下跌。为了保证技术指标和回测的准确性,我们需要对历史价格进行复权处理。QMT 平台虽然在 get_market_data_ex 等接口中内置了自动复权功能,但在某些复杂的自定义策略或因子计算中,我们需要手动获取复权因子并进行精确计算。

本文将详细介绍如何利用 QMT 的 ContextInfo.get_divid_factors() 接口获取除权除息数据,并使用 Python 手动计算历史前复权价格。


1. 接口介绍:ContextInfo.get_divid_factors()

  • 方法定义ContextInfo.get_divid_factors(stock_code)
  • 参数stock_code (string),格式为 'code.market',例如 '600000.SH'
  • 返回值dict,返回一个除权除息日(时间戳)与复权因子的映射字典。

2. 前复权价格计算原理

前复权是以当前最新价格为基准,保持最新价格不变,将历史价格往下拉低。其计算公式为:

$$\text{前复权价格} = \text{原始历史价格} \times \text{对应历史时期的复权因子}$$

在 QMT 返回的复权因子字典中,键(Key)为除权除息日的时间戳,值(Value)为该除权日对应的复权比例因子。


3. 完整 Python 策略源码示例

以下代码展示了如何在 handlebar 中获取浦发银行(600000.SH)的除权因子,获取其不复权的历史收盘价,并手动计算出前复权价格:

#encoding:gbk
import pandas as pd

def init(ContextInfo):
    # 设定基础股票池
    ContextInfo.stock = '600000.SH'
    ContextInfo.set_universe([ContextInfo.stock])

def handlebar(ContextInfo):
    # 仅在最后一根Bar运行一次,避免重复计算
    if not ContextInfo.is_last_bar():
        return
    
    stock = ContextInfo.stock
    
    # 1. 获取除权除息日和复权因子
    # 返回格式如:{1512748800000: 0.8543, 1544198400000: 0.9122}
    factors_dict = ContextInfo.get_divid_factors(stock)
    if not factors_dict:
        print(f"{stock} 没有查询到复权因子数据,可能未发生过除权。")
        return
        
    print("--- 原始复权因子数据 ---")
    for k, v in factors_dict.items():
        # 将毫秒时间戳转换为可读日期
        date_str = timetag_to_datetime(k, '%Y%m%d')
        print(f"除权除息日: {date_str}, 复权因子: {v}")

    # 2. 获取不复权的历史日线收盘价
    # 使用 get_market_data_ex 获取 DataFrame 格式数据
    raw_data = ContextInfo.get_market_data_ex(
        fields=['close'], 
        stock_code=[stock], 
        period='1d', 
        dividend_type='none', # 明确指定不复权
        count=100
    )
    
    df = raw_data[stock]
    df.index = pd.to_datetime(df.index) # 转换索引为时间格式
    df['raw_close'] = df['close']
    df['adj_close'] = df['raw_close'] # 初始化前复权价格列
    
    # 3. 手动计算前复权价格
    # 将复权因子字典转换为 DataFrame 方便与行情数据对齐
    factor_list = []
    for k, v in factors_dict.items():
        date_str = timetag_to_datetime(k, '%Y-%m-%d')
        factor_list.append({'date': date_str, 'factor': v})
    
    df_factors = pd.DataFrame(factor_list)
    df_factors['date'] = pd.to_datetime(df_factors['date'])
    df_factors.set_index('date', inplace=True)
    df_factors.sort_index(inplace=True)
    
    # 将复权因子合并到行情 DataFrame 中,并向后填充(ffill)
    df = df.join(df_factors, how='left')
    # 最新日期之后的因子设为 1.0(即不复权)
    df['factor'] = df['factor'].bfill().fillna(1.0) 
    
    # 计算前复权价格
    df['manual_adj_close'] = df['raw_close'] * df['factor']
    
    # 4. 打印对比结果
    print("\n--- 手动复权计算结果对比 (前10行) ---")
    print(df[['raw_close', 'factor', 'manual_adj_close']].head(10))

4. 注意事项

  1. 数据补充:在使用 get_divid_factors 接口前,请务必通过 QMT 客户端的 “数据管理” -> “补充数据” 功能,下载对应市场的历史除权除息数据,否则可能获取到空字典。
  2. 时间戳转换:接口返回的除权日为毫秒级时间戳,可以使用 QMT 内置的 timetag_to_datetime(timetag, format) 函数将其转换为标准日期格式,便于与 Pandas 的 DatetimeIndex 进行对齐拼接。