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

ptrade 平台如何利用 get_stock_exrights 因子手动计算前复权价格?(附 Python 源码)

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

问题描述

ptrade 数据处理:利用 get_stock_exrights 的前复权因子手动还原真实历史股价
ptrade 获取除权除息数据后,怎么用 exer_forward_a 和 B 因子自己算出前复权价格?

解决方案

ptrade 数据处理:利用 get_stock_exrights 的前复权因子手动还原真实历史股价

在量化交易中,为了保证历史价格序列的连续性,避免因除权除息(送股、分红、配股等)导致的价格断层,我们通常需要使用复权价格。ptrade 提供了 get_stock_exrights 接口,允许用户获取历史所有的除权除息因子,从而可以手动精准计算前复权价格。


一、前复权计算公式

根据 ptrade API 文档,前复权的计算公式如下:

$$\text{前复权价格} = A \times \text{不复权价格} + B$$

其中:

  • $A$:前复权除权因子 A(对应返回字段 exer_forward_a
  • $B$:前复权除权因子 B(对应返回字段 exer_forward_b

二、手动计算前复权的步骤

  1. 获取不复权历史行情:调用 get_historyget_price,设置 fq=None(不复权)。
  2. 获取除权除息数据:调用 get_stock_exrights(stock_code) 获取该股票的历史除权除息因子 DataFrame。
  3. 数据对齐与填充:将行情数据与除权除息数据按日期进行对齐。对于没有发生除权除息的交易日,默认因子 $A = 1.0$,$B = 0.0$。
  4. 应用公式计算:利用公式 A * close + B 算出每日的前复权收盘价。

三、Python 策略源码示例

以下是一个完整的 ptrade 策略示例,展示了如何在 handle_data 中手动计算前复权价格:

import pandas as pd
import numpy as np

def initialize(context):
    g.security = '600570.SS'  # 恒生电子
    set_universe(g.security)

def handle_data(context, data):
    # 1. 获取过去 100 天的不复权收盘价
    df_history = get_history(100, '1d', ['close'], security_list=g.security, fq=None)
    
    # 提取单只股票的 DataFrame,并将索引转换为 YYYYMMDD 格式的整数或字符串以便对齐
    df_price = df_history.query('code in ["600570.SS"]').copy()
    df_price['date_str'] = df_price.index.strftime('%Y%m%d')
    
    # 2. 获取该股票的历史除权除息信息
    df_exrights = get_stock_exrights(g.security)
    
    if df_exrights is not None:
        # 将除权除息表的索引(date)转换为 str 类型以便与价格表匹配
        df_exrights.index = df_exrights.index.astype(str)
        
        # 3. 将除权除息因子合并到价格表中
        df_merged = pd.merge(df_price, df_exrights[['exer_forward_a', 'exer_forward_b']], 
                             left_on='date_str', right_index=True, how='left')
        
        # 对于没有除权除息的日期,因子 A 默认为 1,B 默认为 0
        df_merged['exer_forward_a'] = df_merged['exer_forward_a'].fillna(1.0)
        df_merged['exer_forward_b'] = df_merged['exer_forward_b'].fillna(0.0)
        
        # 4. 手动计算前复权价格
        df_merged['manual_forward_close'] = df_merged['exer_forward_a'] * df_merged['close'] + df_merged['exer_forward_b']
        
        # 打印对比结果
        log.info("\n" + str(df_merged[['close', 'exer_forward_a', 'exer_forward_b', 'manual_forward_close']].tail(10)))
    else:
        log.info("该股票历史无除权除息数据,前复权价格等于原价格。")

四、注意事项

  1. 未来数据规避:手动复权时,请确保使用的除权除息因子发布日期在当前回测时间之前,避免引入未来函数。
  2. 数据缺失处理:若 get_stock_exrights 返回 None,说明该标的历史上从未发生过除权除息,此时前复权价格直接等于不复权价格。
  3. 精度问题:由于浮点数计算精度问题,手动计算的结果与系统直接获取的 fq='pre' 可能会有微小的末位差异,这属于正常现象。