事件研究法Python代码
发布时间
阅读量:
阅读量
事件研究法(event study),根据研究目的选择某一特定事件,研究事件发生前后样本股票收益率的变化,进而解释特定事件对样本股票价格变化与收益率的影响,主要被用于检验事件发生前后价格变化或价格对披露信息的反应程度。
主要步骤,如下所示:
1.定义事件;
2.选择研究样本;
3.选择模型(指的是数据回归模型,比如CAPM);
4.估计异常收益;
5. 检验异常收益;
所使用的代码,参考了现在网上见到的代码,并做了一些修改,添加了AR以及CAR的显著性检验,就是事件研究法的最后部分。(不过,我的数据不太好,最后的结果不是太理想。就不放上来了……)
!!!注:本文使用的是tushare的pro接口,但是需要积分,积分可以在注册时候获取,需要做一些任务。高校学生或者老师可以通过认证的方式获取积分,可以免费试用3个月,之后可以通过季度任务续期,还挺方便划算的~
如果choice或者wind数据获取以及整理比较麻烦的话,tushare挺方便的!
# 事件研究法
import pandas as pd
import tushare as ts
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
# 线性回归
import csv import numpy as np
import math
plt.rcParams['font.sans-serif'] = ['SimHei'] # 中文
plt.rcParams['axes.unicode_minus'] = False
pro = ts.pro_api('个人 tushare 端口代码')
plt.style.use('fivethirtyeight')
# 市场收益率
Rm df = pro.index_daily(ts_code='市场代码', start_date='20100101', end_date='20220101') df_index = df[['trade_date', 'pct_chg']].copy()
df_index['trade_date'] = pd.to_datetime(df_index['trade_date'])
df_index = df_index.sort_values("trade_date")
df_index = df_index.reset_index().drop("index", axis=1)
df_index['pct_chg'] = df_index['pct_chg'] / 100
# 企业收益率
Ri ts_code = '企业代码' d2 = pro.index_daily(ts_code=ts_code, start_date='20100101', end_date='20220101')
d0 = d2[['trade_date', 'pct_chg']].copy()
d0.columns = ['trade_date', 'return']
d0['trade_date'] = pd.to_datetime(d0['trade_date'])
d0 = d0.sort_values("trade_date")
d0 = d0.reset_index().drop("index", axis=1)
d0['return'] = d0['return'] / 100
# 合并 Ri 和 Rm
df_final = d0.merge(df_index, on='trade_date', how='left')
df_final.to_excel("整理数据.xlsx")
# 计算预期收益率
def get_OLS(X, y, pre_X):
linear_m = LinearRegression().fit(X, y)
r_2 = linear_m.score(X, y) # 值越接近1拟合优度越好
pre_y = linear_m.predict(X)
Residual = sum((y - pre_y) ** 2)
L_xx = len(X) * np.var(X)
sigma = np.sqrt(Residual / (len(X) - 2))
t = linear_m.coef_ * np.sqrt(L_xx) / sigma
t = round(float(t), 4)
print(f"构建模型,拟合优度为{round(r_2 * 100, 2)}%")
print(f"Ri = {round(linear_m.intercept_, 3)} + {round(linear_m.coef_[0], 3)}Rm + e")
if 1.65 <= abs(t) < 1.96:
print(f'回归模型的t值为{t},回归系数在10%的置信水平下显著')
elif 1.96 <= abs(t) < 2.58:
print(f'回归模型的t值为{t},回归系数在5%的置信水平下显著')
elif abs(t) >= 2.58:
print(f'回归模型的t值为{t},回归系数在1%的置信水平下显著')
else:
print(f'回归模型的t值为{t},回归系数不显著')
return linear_m.predict(pre_X)
# 计算AR,CAR
def get_data(event):
print("事件日为: ", event)
q, h = df_final[df_final['trade_date'] == event].index[0] - 15, df_final[df_final['trade_date'] == event].index[0] + 15 # 事件窗口[-15,15]
target = df_final.loc[q:h].copy()
estimate = df_final.loc[q - 195:q - 6].copy() # 估计窗口[-210,-21]
X = estimate[['pct_chg']] # 估计期市场回报率
y = estimate['return'] # 估计期企业回报率
predict_X = target[['pct_chg']] # 窗口期市场回报率
target['E(Rt)'] = get_OLS(X, y, predict_X) # 企业预期收益率
target['ARt'] = target['return'] - target['E(Rt)'] # 企业异常收益率
target['CARt'] = target['ARt'].cumsum() # 累计异常收益率 = 异常收益率在窗口期的求和
return target
# 绘制图像
def main(e):
a = get_data(e)
a.to_excel('data.xls',index=False)
AR = a['ARt']
CAR = a['CARt']
theta1 = np.mean(AR)/math.sqrt(np.var(AR))
theta2 = np.mean(CAR)/math.sqrt(np.var(CAR))
print('theta1:',theta1)
print('theta2:',theta2)
a.set_index('trade_date')[['ARt', 'CARt']].plot()
# 结果
events = ['事件发生日期 00:00:00']
for e in events:
main(e)
plt.title('企业名称')
plt.savefig('.\企业名称.jpg', bbox_inches='tight')
补充一下具体的统计量~
希望能对大家有帮助!
全部评论 (0)
还没有任何评论哟~
