pandas_计算前复权收盘价和后复权收盘价

目录

已知条件:

概念描述:

 开始计算:

 读入数据

 计算复权因子

 计算前复权因子

 计算后复权因子

 计算前复权收盘价

计算后复权收盘价 

 数据:


本文以恒瑞医药上市以来至2022-07-06的数据作为讲解素材,数据在本文最后会提供下载。

注:本文计算不考虑扣税

已知条件:

1. 恒瑞医药上市以来无复权收盘价数据

文件名:pre_600276_data.csv

字段说明:secID:股票编码,tradeDate:交易日期,closePrice:收盘价

2. 恒瑞医药上市以来分红数据

文件名:pre_600276_bonus.csv

字段说明:registerDate:股权登记日,exDivDate:除权除息日,perCashDiv:每股派息(现金分红),perShareDivRatio:每股送股,perShareTransRatio:每股转增,programmeTxt:分红的文字描述

概念描述:

1. 上市公司在送股后,股票的数量变多,但公司价值不变,股价变低,在K线图上就会出现一个缺口,涨跌幅变得不合理,很多指标通过这样的数据计算出来基本不可用,所以就需要修补这个缺口,这个过程就叫复权。

pandas_计算前复权收盘价和后复权收盘价_第1张图片
2. 复权有分前复权和后复权,比较通用的是前复权,一般指标的计算都是使用前复权数据
3. 前复权是以最近一次的除权日为起点,往前回溯对数据进行调整,可以粗糙地理解是把以前的数据往下平移,去除缺口
前复权后价格=(复权前价格-现金红利)/(1+流通股份变动比例)
这里的“复权前价格”是股权登记日的收盘价

pandas_计算前复权收盘价和后复权收盘价_第2张图片
4. 后复权要看我们使用的数据以什么时候为起点,可以是上市当日,也可以自己任意取一个开始日期,可以粗糙地理解是从开始日期把往后的数据向上平移,去除缺口
后复权后价格=复权前价格×(1+流通股份变动比例)+现金红利
这里的“复权前价格”是除权除息日的收盘价

pandas_计算前复权收盘价和后复权收盘价_第3张图片

 开始计算:

import pandas as pd
pd.set_option('display.max_columns',None)
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
plt.figure(figsize=(20,10))
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

 读入数据

df_noright_data = pd.read_csv('pre_600276_data.csv',encoding='utf-8')
df_noright_data.head()

pandas_计算前复权收盘价和后复权收盘价_第4张图片

df_bouns = pd.read_csv('pre_600276_bonus.csv',encoding='utf-8')
df_bouns.head()

pandas_计算前复权收盘价和后复权收盘价_第5张图片

 计算复权因子

# 计算复权因子,所有计算都不考虑税费
df_adjust_factor = df_bouns.loc[:,['registerDate','exDivDate','perCashDiv','perShareDivRatio','perShareTransRatio']].copy()
df_adjust_factor['registerDate'] = pd.to_datetime(df_adjust_factor['registerDate'])
df_adjust_factor['exDivDate'] = pd.to_datetime(df_adjust_factor['exDivDate'])
# 将“股权登记日registerDate”对应的未复权收盘价加入 df_adjust_factor 表,字段名为 register_close_price
df_noright_data['tradeDate'] = pd.to_datetime(df_noright_data['tradeDate'])
def input_register_close_price(x):
    target_date = x['registerDate']
    target_close = df_noright_data[df_noright_data['tradeDate']==target_date].iloc[0]['closePrice']
    return target_close
df_adjust_factor['register_close_price'] = df_adjust_factor.apply(input_register_close_price,axis=1)
df_adjust_factor.head()

pandas_计算前复权收盘价和后复权收盘价_第6张图片

# 将“除权除息日exDivDate”对应的未复权收盘价加入 df_adjust_factor 表,字段名为 except_close_price
def input_except_close_price(x):
    target_date = x['exDivDate']
    target_close = df_noright_data[df_noright_data['tradeDate']==target_date].iloc[0]['closePrice']
    return target_close
df_adjust_factor['except_close_price'] = df_adjust_factor.apply(input_except_close_price,axis=1)
df_adjust_factor.head()

pandas_计算前复权收盘价和后复权收盘价_第7张图片

 计算前复权因子

1. 前复权后价格=(复权前价格-现金红利)/(1+流通股份变动比例)
2. 计算的是“股权登记日”的收盘价
3. 前复权因子 = 前复权后价格/复权前价格
4. 前复权除权因子,为本次股权登记日为起点,往前开始累乘,所得到的数值为“前复权除权因子”,这样历史未复权收盘价乘以前复权除权因子后就是前复权收盘价

# 计算前复权因子
'''
前复权后价格=(复权前价格-现金红利)/(1+流通股份变动比例)
计算的是“股权登记日”的收盘价
前复权因子 = 前复权后价格/复权前价格
前复权除权因子,为本次股权登记日为起点,往前开始累乘,所得到的数值为“前复权除权因子”,这样历史未复权收盘价乘以前复权除权因子后就是前复权收盘价
'''
# 定义前复权因子字段名 pre_single_factor
def caculate_preSingleFactor(x):
    perCashDiv = x['perCashDiv'] if not np.isnan(x['perCashDiv']) else 0   # 每股派息
    perShareDivRatio = x['perShareDivRatio'] if not np.isnan(x['perShareDivRatio']) else 0  # 每股送股
    perShareTransRatio = x['perShareTransRatio'] if not np.isnan(x['perShareTransRatio']) else 0 # 每股转增
    ori_price = x['register_close_price']
    target_price = (ori_price-perCashDiv)/(1+perShareDivRatio+perShareTransRatio)
    target_radio = target_price/ori_price
    return target_radio
df_adjust_factor['pre_single_factor'] = df_adjust_factor.apply(caculate_preSingleFactor,axis=1)
df_adjust_factor.head()

pandas_计算前复权收盘价和后复权收盘价_第8张图片

# 定义前复权除权因子字段名 pre_accum_factor
df_adjust_factor['pre_accum_factor'] = df_adjust_factor['pre_single_factor'].cumprod()
df_adjust_factor.head()

pandas_计算前复权收盘价和后复权收盘价_第9张图片

 计算后复权因子

1. 后复权后价格=复权前价格×(1+流通股份变动比例)+现金红利
2. 计算的是“除权除息日”的收盘价
3. 后复权因子 = 后复权后价格/复权前价格
4. 后复权除权因子,要看你的收盘价数据是以什么时间为起点,你收盘价数据的起点就是后复权除权因子计算的起点,往后开始累乘后复权因子,所得到的数值为“后复权除权因子”,这样历史未复权收盘价乘以后复权除权因子后就是后复权收盘价

# 计算后复权因子
'''
后复权后价格=复权前价格×(1+流通股份变动比例)+现金红利
计算的是“除权除息日”的收盘价
后复权因子 = 后复权后价格/复权前价格
后复权除权因子,要看你的收盘价数据是以什么时间为起点,你收盘价数据的起点就是后复权除权因子计算的起点,往后开始累乘后复权因子,\
所得到的数值为“后复权除权因子”,这样历史未复权收盘价乘以后复权除权因子后就是后复权收盘价
'''
# 定义后复权因子字段名 after_single_factor
def caculate_afterSingleFactor(x):
    perCashDiv = x['perCashDiv'] if not np.isnan(x['perCashDiv']) else 0   # 每股派息
    perShareDivRatio = x['perShareDivRatio'] if not np.isnan(x['perShareDivRatio']) else 0  # 每股送股
    perShareTransRatio = x['perShareTransRatio'] if not np.isnan(x['perShareTransRatio']) else 0 # 每股转增
    ori_price = x['except_close_price']
    target_price = ori_price*(1+perShareDivRatio+perShareTransRatio)+perCashDiv
    target_radio = target_price/ori_price
    return target_radio
df_adjust_factor['after_single_factor'] = df_adjust_factor.apply(caculate_afterSingleFactor,axis=1)
df_adjust_factor.head()

pandas_计算前复权收盘价和后复权收盘价_第10张图片

# 定义后复权除权因子字段名 after_accum_factor
df_temp = df_adjust_factor.loc[:,['exDivDate','after_single_factor']].copy()
df_temp.sort_values(by='exDivDate',ascending=True,inplace=True)
df_temp.head()

pandas_计算前复权收盘价和后复权收盘价_第11张图片

df_temp['after_accum_factor'] = df_temp['after_single_factor'].cumprod()
df_temp.tail()

pandas_计算前复权收盘价和后复权收盘价_第12张图片

df_temp.sort_values(by='exDivDate',ascending=False,inplace=True)
df_adjust_factor['after_accum_factor'] = df_temp['after_accum_factor']
df_adjust_factor.head()

pandas_计算前复权收盘价和后复权收盘价_第13张图片

 计算前复权收盘价

前复权收盘价 = 无复权收盘价*前复权除权因子

# 计算前复权收盘价
df_pre_data = df_noright_data.loc[:,['tradeDate','closePrice']].copy()
df_pre_factor = df_adjust_factor.loc[:,['registerDate','pre_accum_factor']].copy()
df_pre_factor.rename(columns={'registerDate':'tradeDate'},inplace=True)
df_pre_factor.head()

pandas_计算前复权收盘价和后复权收盘价_第14张图片

df_pre_data = pd.merge(df_pre_data,df_pre_factor,on='tradeDate',how='left')
df_pre_data.head()

pandas_计算前复权收盘价和后复权收盘价_第15张图片

df_pre_data.tail()

pandas_计算前复权收盘价和后复权收盘价_第16张图片

df_pre_data['pre_accum_factor'] = df_pre_data['pre_accum_factor'].fillna(method='bfill',axis=0)
df_pre_data.tail()

pandas_计算前复权收盘价和后复权收盘价_第17张图片

df_pre_data['pre_accum_factor'] = df_pre_data['pre_accum_factor'].fillna(1,axis=0)
df_pre_data.tail()

 pandas_计算前复权收盘价和后复权收盘价_第18张图片

df_pre_data['adj_close'] = df_pre_data['closePrice']*df_pre_data['pre_accum_factor']
df_pre_data.plot(x='tradeDate',y=['closePrice','adj_close'])

pandas_计算前复权收盘价和后复权收盘价_第19张图片

计算后复权收盘价 

后复权收盘价 = 无复权收盘价*后复权除权因子

# 计算后复权收盘价
df_after_data = df_noright_data.loc[:,['tradeDate','closePrice']].copy()
df_after_factor = df_adjust_factor.loc[:,['exDivDate','after_accum_factor']].copy()
df_after_factor.rename(columns={'exDivDate':'tradeDate'},inplace=True)
df_after_data = pd.merge(df_after_data,df_after_factor,on='tradeDate',how='left')
df_after_data.head()

pandas_计算前复权收盘价和后复权收盘价_第20张图片

df_after_data.tail()

pandas_计算前复权收盘价和后复权收盘价_第21张图片

df_after_data['after_accum_factor'] = df_after_data['after_accum_factor'].fillna(method='ffill',axis=0)
df_after_data.tail()

pandas_计算前复权收盘价和后复权收盘价_第22张图片

df_after_data.head()

pandas_计算前复权收盘价和后复权收盘价_第23张图片

df_after_data['after_accum_factor'] = df_after_data['after_accum_factor'].fillna(1,axis=0)
df_after_data['adj_close'] = df_after_data['closePrice']*df_after_data['after_accum_factor']
df_after_data.plot(x='tradeDate',y=['closePrice','adj_close'])

pandas_计算前复权收盘价和后复权收盘价_第24张图片

 数据:

链接:https://pan.baidu.com/s/104dpG734M5kD4cjMsYkGgw 
提取码:souj

你可能感兴趣的:(pandas基础与金融实例练习,python,pandas,金融)