4、复权数据处理:前复权与后复权原理、除权除息数据修正、复权因子计算
做量化交易,最怕什么?
怕数据有坑。
而「复权」就是最大的坑之一。我刚开始做回测时,拿到的股票数据直接扔进策略,结果收益率曲线漂亮得不像话。后来一查,原来是没处理复权,把分红送股当成了白捡的钱。嗯,那叫一个尴尬。
4.1 为什么需要复权?
股票会分红、送股、配股。这些操作会导致股价在除权除息日出现「断崖式下跌」。比如一只股票100块,每10股派10元,除息日开盘价就变成99块。你想想看,这1块钱的缺口不是市场波动,是钱真的到你账户里了。
但如果你直接用原始价格做回测,策略会认为股价跌了1%,触发止损。这就完全失真了。
复权的目的:消除分红送股对价格序列的「非市场性扰动」,让价格曲线连续可分析。
4.2 前复权 vs 后复权
这两个概念,说白了就是「调整基准日」不同。
| 类型 | 调整方式 | 当前价格 | 历史价格 | 适用场景 |
|---|---|---|---|---|
| 前复权 | 调整历史价格,保持最新价格不变 | 真实价格 | 被调低 | 回测、技术分析 |
| 后复权 | 调整历史价格,保持上市首日价格不变 | 被调高 | 真实价格 | 长期趋势分析 |
我个人习惯用前复权做回测。为什么?因为前复权下,最新价格就是真实成交价,你看到的K线形态、均线系统都和实盘一致。后复权的话,当前价格可能被放大到几百甚至上千块,看着怪别扭的。
4.3 除权除息数据修正
要算复权,先得搞清楚「除权除息」到底发生了什么。我遇到过不少新手,直接把分红金额加到股价上,结果算出来的复权因子全是错的。
除权除息主要分三种情况:
- 现金分红:股价减去每股分红。比如10派5元,每股除息0.5元。
- 送股/转增:股价按比例下调。比如10送10,股价直接腰斩。
- 配股:比较复杂,需要按配股价和配股比例加权平均。
修正公式其实很简单:
除权除息参考价 = (前收盘价 - 每股现金分红 + 配股价 × 配股比例) / (1 + 送股比例 + 转增比例 + 配股比例)
举个例子:某股票前收盘20元,10派5元(每股0.5元),10送5(送股比例0.5),没有配股。
除权参考价 = (20 - 0.5) / (1 + 0.5) = 19.5 / 1.5 = 13元
你看,从20跌到13,不是市场跌了35%,是公司把一部分价值变成了现金和股票给了你。
4.4 复权因子计算
复权因子,说白了就是一个「乘数」。你拿着这个乘数去乘原始价格,就能得到复权后的价格。
计算步骤:
- 从上市首日或某个基准日开始,逐日计算复权因子。
- 遇到除权除息日,根据除权比例更新因子。
- 非除权日,因子保持不变。
前复权因子的计算公式:
复权因子(t) = 复权因子(t-1) × (1 + 送股比例 + 转增比例 + 配股比例) / (前收盘价 - 每股现金分红 + 配股价 × 配股比例) × 前收盘价
嗯,看着有点绕。我一般直接用Python算:
import pandas as pd
def calc_forward_adj_factor(df):
"""
df: 包含日期、收盘价、每股分红、送股比例、配股比例、配股价
返回前复权因子序列
"""
df = df.sort_values('date', ascending=False) # 从最新往最早算
factor = [1.0]
for i in range(1, len(df)):
prev_close = df.iloc[i-1]['close']
cash_div = df.iloc[i]['cash_div']
stock_div = df.iloc[i]['stock_div']
rights_ratio = df.iloc[i]['rights_ratio']
rights_price = df.iloc[i]['rights_price']
# 除权除息日调整
if cash_div > 0 or stock_div > 0 or rights_ratio > 0:
adj_factor = (prev_close - cash_div + rights_price * rights_ratio) / \
(prev_close * (1 + stock_div + rights_ratio))
factor.append(factor[-1] * adj_factor)
else:
factor.append(factor[-1])
df['adj_factor'] = factor[::-1] # 反转回时间正序
df['adj_close'] = df['close'] * df['adj_factor']
return df
4.5 复权数据的实战要点
做量化这几年,我总结了几条关于复权的铁律:
- 回测必须用前复权:否则你的买入卖出信号全是错的。
- 不要用复权数据算分红收益率:复权后的价格已经包含了分红影响,再用它算股息率会重复计算。
- 多数据源交叉验证:不同数据商的复权算法可能有细微差异。我习惯同时拉两个数据源,对比复权因子是否一致。
- 新股上市前5日不参与复权:有些数据商会把上市首日的涨跌幅也纳入复权计算,这会导致因子失真。
4.6 知识体系总览
下面这张图,是我自己梳理的复权数据处理全流程。每次做数据清洗时,我都会对照着检查一遍。
这张图把复权处理的流程串起来了。从原始数据出发,先识别除权除息事件,然后根据事件类型分别处理,最后计算出复权因子,生成前复权或后复权价格序列。每一步都有坑,每一步都需要验证。
好了,复权这块就聊到这儿。记住一句话:不复权的回测,都是耍流氓。
公众号:蓝海数据掘金营,微信deep3321