'''import tushare as ts
pro = ts.pro_api('a492ea4daxxxxxxxxxxxxxxxxxxx12f4a655e21')
# 获取shibor(1个月)数据作为无风险收益率
shibor_history=pro.shibor(start_date='20170101',end_date='20211231',fields='date,1m')
shibor_history.to_csv('E:\\python_outputs\\CAPM\\shibor_history.csv',index=False)
# 获取沪深300指数月线数据
HS300_history=pro.index_monthly(ts_code='000300.SH',start_date='20161201',end_date='20211231',
fields='ts_code,trade_date,close')
HS300_history.to_csv('E:\\python_outputs\\CAPM\\HS300_history.csv',index=False)
# 获取沪深300指数成份股(2021年12月31日)
cons_HS300=pro.index_weight(index_code='000300.SH',trade_date='20211231',
fields='con_code,trade_date')
cons_HS300.to_csv('E:\\python_outputs\\CAPM\\cons_HS300.csv',index=False)
# 获取沪深300所有成份股的月线数据
# 抱歉,您每分钟最多访问该接口120次
import time
for i in cons_HS300.truncate(before=0,after=99).con_code:
con=pro.monthly(ts_code=i,start_date='20161201',end_date='20211231',fields='ts_code,trade_date,close')
con.to_csv('E:\\python_outputs\\CAPM\\cons_monthly\\{}_monthly.csv'.format(i),index=False)
time.sleep(61) # 等待61秒
for i in cons_HS300.truncate(before=100,after=199).con_code:
con=pro.monthly(ts_code=i,start_date='20161201',end_date='20211231',fields='ts_code,trade_date,close')
con.to_csv('E:\\python_outputs\\CAPM\\cons_monthly\\{}_monthly.csv'.format(i),index=False)
time.sleep(61) # 等待61秒
for i in cons_HS300.truncate(before=200,after=299).con_code:
con=pro.monthly(ts_code=i,start_date='20161201',end_date='20211231',fields='ts_code,trade_date,close')
con.to_csv('E:\\python_outputs\\CAPM\\cons_monthly\\{}_monthly.csv'.format(i),index=False)'''
# ======================================== ^ Step1 数据获取 ^ ================================================= #
import glob
import numpy as np
import pandas as pd
HS300=pd.read_csv('E:\\python_outputs\\CAPM\\HS300_history.csv',parse_dates=['trade_date'])
HS300.trade_date=HS300.trade_date.apply(lambda x:x.strftime('%Y%m')) # 日期转为年月格式
# print(HS300)
df=pd.read_csv('E:\\python_outputs\\CAPM\\shibor_history.csv',parse_dates=['date'],index_col='date')
df0=(df.resample('M') # 调整周期,以月为周期
.mean()
.div(12) # shibor利率为单利年利,直接出除以12
.reset_index())
df0.date=df0.date.apply(lambda x:x.strftime('%Y%m'))
shibor=df0.rename(columns={'date':'trade_date','1m':'rf_shibor'}).set_index('trade_date')
shibor.to_csv('E:\\python_outputs\\CAPM\\rf_shibor.csv')
# print(shibor)
files=glob.glob('E:\\python_outputs\\CAPM\\cons_monthly\\*.csv')
cons_monthly=pd.concat([pd.read_csv(j,parse_dates=['trade_date']) for j in files])
cons_monthly.trade_date=cons_monthly.trade_date.apply(lambda x:x.strftime('%Y%m'))
# print(cons_monthly)
data=(pd.concat([cons_monthly,HS300])
.set_index('trade_date')
.pivot(columns='ts_code',values='close')
.dropna(axis=1)
.apply(np.log)
.diff()
.dropna()
.mul(100))
regression_data_set=(data.T-shibor.T.loc['rf_shibor']).T # regression_data_set为成分股和沪深300的历史超额收益率
regression_data_set.to_csv('E:\\python_outputs\\CAPM\\regression_data_set.csv')
# print(regression_data_set)
# ======================================== ^ Step2 数据整理 ^ ================================================= #
import statsmodels.api as sm
import matplotlib.pyplot as plt
regression_data_set=pd.read_csv('E:\\python_outputs\\CAPM\\regression_data_set.csv',index_col='trade_date')
print(regression_data_set)
X=sm.add_constant(regression_data_set['000300.SH'])
params_list=[]
r2_adj_list=[]
cons=regression_data_set.columns
for a in cons:
y=regression_data_set[a]
model=sm.OLS(y,X)
result=model.fit()
param = result.params.to_list()
r2_adj = result.rsquared_adj
params_list.append(param)
r2_adj_list.append(r2_adj)
r2_adj = pd.DataFrame(r2_adj_list, index=cons, columns=['rsquared_adj'])
params = pd.DataFrame(params_list, columns=['const', '000300.SH'], index=cons)
regression_result = pd.concat([params, r2_adj], axis=1)
# print(regression_result)
regression_result.to_csv('E:\\python_outputs\\CAPM\\regression_result.csv')
# 个例展示(贵州茅台)
X1=sm.add_constant(regression_data_set['000300.SH'])
y1=regression_data_set['600519.SH']
model1=sm.OLS(y1,X1)
result1=model1.fit()
print(result1.summary())
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
regression_data_set1=regression_data_set.assign(observes_month=range(1,61))
plt.figure(figsize=(9,5))
plt.plot(regression_data_set1.observes_month,[0]*60,color='black')
plt.plot(regression_data_set1.observes_month,regression_data_set['600519.SH'],label='贵州茅台',linestyle='--')
plt.plot(regression_data_set1.observes_month,regression_data_set['000300.SH'],label='沪深300')
plt.title('沪深300和贵州茅台的超额收益')
plt.xlabel('观察样本(月)')
plt.ylabel('超额收益(%)')
plt.legend()
plt.savefig('E:\\python_outputs\\CAPM\\沪深300和贵州茅台的超额收益.png')
X1=regression_data_set['000300.SH']
Y1=result1.predict()
plt.figure(figsize=(9,6))
plt.scatter(X1,y1,label='观测值')
plt.plot(X1,Y1,label='预测值',color='orange')
plt.title('贵州茅台证券特征线')
plt.xlabel('沪深300超额收益(%)',position=(1,1))
plt.ylabel('贵州茅台超额收益(%)',position=(-5,0.95),rotation=0)
plt.legend()
ax=plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_position(('data',0))
ax.spines['left'].set_position(('data',0))
plt.savefig('E:\\python_outputs\\CAPM\\贵州茅台证券特征线.png')
# plt.show()
# ===================================== ^ Step3 一阶回归和个例(贵州茅台) ^ ====================================== #
regression_result=pd.read_csv('E:\\python_outputs\\CAPM\\regression_result.csv',index_col='Unnamed: 0')
regression_result.rename(columns={'000300.SH':'beta'},inplace=True)
# print(regression_result)
df1=regression_data_set.div(100).add(1).apply(np.cumprod)
# print(df1)
mean_return=df1.loc[202112].apply(lambda s:np.power(s,1/60)).sub(1).mul(100).rename('mean_Return')
X2=sm.add_constant(regression_result['beta'])
y2=mean_return
# print(y2)
model2=sm.OLS(y2,X2)
result2=model2.fit()
print(result2.summary())
# print(df1.loc[202112])
# print(mean_return)
s=regression_data_set.mean()
# print(s)
rf=pd.read_csv('E:\\python_outputs\\CAPM\\rf_shibor.csv',index_col='trade_date')
mean_rf=rf.rf_shibor.mean()
print('mean_rf:','{:.4f}'.format(mean_rf))
X3=regression_result['beta']
Y3=pd.Series(result2.predict()).add(mean_rf)
y3=y2.add(mean_rf)
# print(y3)
plt.figure(figsize=(6,6))
plt.scatter(X3,y3,label='observes')
plt.plot(X3,Y3,label='CML',color='orange')
plt.title('证券市场线')
plt.xlabel('beta',position=(1,1))
plt.ylabel('E(R)',position=(-5,0.95),rotation=0)
plt.legend()
ax=plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_position(('data',0))
ax.spines['left'].set_position(('data',0))
plt.savefig('E:\\python_outputs\\CAPM\\证券市场线.png')
plt.show()
# ======================================== ^ Step2 二阶回归 ^ ================================================= #