3. 基于事件驱动的回测引擎

案例3:处理股票除权除息数据 学习卡片

任务说明

股票在分红、送股或配股时会发生除权除息,导致价格出现非交易性跳空。若直接使用原始价格进行回测,会误判为真实涨跌,产生虚假信号。本案例实现前复权处理:以最新交易日为基准,将历史价格统一调整为除权后的可比价格,确保回测信号基于真实收益。

核心实现

import pandas as pd
import numpy as np

def adjust_forward_price(df):
    """
    对日线数据做前复权处理。
    参数df需包含列:date, close, 以及除权除息因子adjust_factor。
    adjust_factor = 复权因子(由行情接口提供,如baostock的adjustFactor字段)。
    前复权价 = 原始收盘价 * adjust_factor / 最新adjust_factor
    """
    df = df.sort_values('date').copy()
    latest_factor = df['adjust_factor'].iloc[-1]
    df['adj_close'] = df['close'] * df['adjust_factor'] / latest_factor
    return df

# 示例数据(含两次除权:10送5派2元、10配3股配股价8元)
data = {
    'date': ['2023-01-04', '2023-02-01', '2023-03-01', '2023-04-03', '2023-05-08'],
    'close': [10.00, 10.50, 6.80, 7.10, 7.50],
    'adjust_factor': [0.85, 0.85, 1.00, 1.00, 1.00]
}
df = pd.DataFrame(data)
df['date'] = pd.to_datetime(df['date'])

result = adjust_forward_price(df)
print(result[['date', 'close', 'adj_close']].to_string(index=False))

关键逻辑说明

复权因子的含义:某日adjust_factor = 当日收盘价 / 当日实际流通市值对应的基准价。当发生除权除息时,因子会跳变(如示例中从0.85变为1.00),而前复权通过将全部历史价格乘以“最新因子/当日因子”的比值,消除该跳变。示例中2023-03-01除权后价格从10.50降至6.80,但前复权后该日价格变为6.80×1.00/1.00=6.80,而此前价格被等比缩小(如10.00×0.85/1.00=8.50),从而保证收益率连续可比。

落地与验证

依赖安装:本案例仅需pandas和numpy,执行pip install pandas numpy即可。

运行方式:将上述代码保存为adjust_forward.py,运行python adjust_forward.py。

验证方法:观察输出中2023-02-01至2023-03-01的收益率:原始价格为10.50→6.80,收益率为-35.2%(虚假暴跌);前复权价格为8.925→6.80,收益率为-23.8%,该数值对应真实除权后的市场表现。判定标准:若除权日前后前复权收益率的值明显小于原始价格收益率,且所有历史价格均按同一比例缩放,则处理正确。

前复权处理流程与效果 原始价格(除权跳空) 前复权价格(连续可比) 除权日 消除跳空 输入:原始close + adjust_factor 输出:adj_close

判定标准

回测系统接入该函数后,使用adj_close计算收益率与信号。验证通过条件:①除权日前后计算出的日收益率与行情软件前复权数据一致;②将复权后数据用于简单均线策略回测,不会因除权日产生虚假买卖信号。