实证资产定价(Empirical asset pricing)已经发布于Github. 包的具体用法(Documentation)博主将会陆续在CSDN中详细介绍。
Github: GitHub - whyecofiliter/EAP: empirical asset pricing
市场体系风险起源于CAPM(Sharpe,1965),其形式可以是
如果市场处于均衡状态,那么推动资产超额收益的唯一因素就是市场系统风险溢价。一旦资产承担了更多的市场系统风险溢价,就应该支付更多的超额收益。因此,根据该理论,超额收益率与贝塔系数正相关,贝塔系数衡量资产承担的市场系统风险的数量。
在实证研究中,股票按滚动贝塔系数(窗口=12个月)按升序排序,随后分为5或10组。首尾两组股票的平均收益率显著性检验以及相应的组收益升序表明超额收益率与贝塔正相关。一元和二元投资组合分析都进行了。
# %% import packageimport pandas as pdimport sys, ossys.path.append(os.path.abspath(".."))# %% import data# Monthly return of stocks in China security marketmonth_return = pd.read_hdf('.\\data\\month_return.h5', key='month_return')beta = pd.read_hdf('.\\data\\beta.hdf5', key='data')
该数据集包含CSMAR数据集中2000-01-01年至-12-31年间的月度中国A股股票。警告:请勿将此演示中的数据集用于任何商业用途。由于数据已加载,因此需要执行一些预处理程序。
# %% data preprocessing# select the A share stockmonth_return = month_return[month_return['Markettype'].isin([1, 4, 16])]# forward the monthly return for each stock# emrwd is the return including dividendmonth_return['emrwd'] = month_return.groupby(['Stkcd'])['Mretwd'].shift(-1)# emrnd is the return including no dividendmonth_return['emrnd'] = month_return.groupby(['Stkcd'])['Mretnd'].shift(-1)# % distinguish the stocks whose size is among the up 30% stocks in each monthdef percentile(stocks) :return stocks >= stocks.quantile(q=.3)month_return['cap'] = month_return.groupby(['Trdmnt'])['Msmvttl'].apply(percentile)
构建市场投资组合回报
# %% construct market portfolio returnimport numpy as npmarket_portfolio_return = month_return['Mretwd'].groupby(month_return['Trdmnt']).apply(np.mean)market_portfolio_return.name = 'market_portfolio_return'month_return = pd.merge(month_return, market_portfolio_return, on=['Trdmnt'])month_return = month_return.sort_values(['Stkcd', 'Trdmnt'])
计算beta
# %% calculate betaimport statsmodels.api as smimport numpy as npreg = month_return.set_index(['Stkcd', 'Trdmnt'])[['Mretwd', 'market_portfolio_return']].dropna()beta = pd.Series(index=reg.index, dtype=float, name='beta')for i in reg.groupby('Stkcd'):row, col = np.shape(i[1])for j in range(row-12):model = sm.OLS(i[1].iloc[j:j+12, 0], sm.add_constant(i[1].iloc[j:j+12, 1])).fit()beta.loc[i[1].index[j+11]] = model.params[1]reg = pd.merge(reg, beta, left_index=True, right_index=True)
数据进一步预处理
# %% Data preprocessing: merge datamonth_return['Date_merge'] = pd.to_datetime(month_return['Trdmnt'])month_return = month_return.set_index(['Stkcd', 'Trdmnt'])month_return = pd.merge(month_return, beta, left_index=True, right_index=True)# construct label# data starts from 2000-01return_company = month_return[month_return['Date_merge']>='2000-01']
由于IPO的具体要求,一些占主导地位的公司会收购一家小型上市公司,并加入a股市场。因此,在Liu等人()的研究中,规模低于30%的股票被放弃。
# %% construct test_data for bivariate analysis# dataset 1from portfolio_analysis import Bivariate, Univariateimport numpy as np# select stocks whose size is among the up 30% stocks in each month and whose trading # days are more than or equal to 10 daystest_data_1 = return_company[(return_company['cap']==True) & (return_company['Ndaytrd']>=10)]test_data_1 = test_data_1[['emrwd', 'Msmvttl', 'beta', 'Date_merge']].dropna()test_data_1 = test_data_1[(test_data_1['Date_merge'] >= '2000-01-01') & (test_data_1['Date_merge'] <= '-12-01')]# Univariate analysisuni_1 = Univariate(np.array(test_data_1[['emrwd', 'beta', 'Date_merge']]), number=9)uni_1.summary_and_test()uni_1.print_summary_by_time()uni_1.print_summary()===================================================================================================+---------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+| Group | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Diff |+---------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+| Average | 0.006 | 0.01 | 0.011 | 0.012 | 0.013 | 0.011 | 0.012 | 0.011 | 0.012 | 0.007 | 0.001 || T-Test | 1.213 | 1.937 | 1.996 | 2.017 | 2.155 | 1.752 | 1.905 | 1.74 | 1.745 | 1.02 | 0.294 |+---------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+===================================================================================================# Bivariate analysisbi_1 = Bivariate(np.array(test_data_1), number=4)bi_1.average_by_time()bi_1.summary_and_test()bi_1.print_summary_by_time()bi_1.print_summary()===============================================================+-------+-------+--------+--------+--------+--------+--------+| Group | 1 | 2 | 3 | 4 | 5 | Diff |+-------+-------+--------+--------+--------+--------+--------+| 1 | 0.009 | 0.014 | 0.014 | 0.015 | 0.014 | 0.005 || | 1.436 | 2.308 | 2.093 | 2.179 | 1.888 | 1.85 || 2 | 0.006 | 0.013 | 0.013 | 0.013 | 0.011 | 0.005 || | 0.996 | 2.115 | 2.008 | 1.931 | 1.633 | 2.147 || 3 | 0.008 | 0.01 | 0.01 | 0.01 | 0.008 | 0.001 || | 1.333 | 1.779 | 1.669 | 1.603 | 1.174 | 0.24 || 4 | 0.008 | 0.009 | 0.01 | 0.011 | 0.008 | 0.0 || | 1.496 | 1.66 | 1.622 | 1.687 | 1.173 | 0.065 || 5 | 0.009 | 0.01 | 0.013 | 0.01 | 0.006 | -0.003 || | 1.928 | 1.882 | 2.103 | 1.533 | 0.86 | -0.914 || Diff | 0.0 | -0.004 | -0.001 | -0.005 | -0.008 | -0.008 || | 0.106 | -1.31 | -0.301 | -1.425 | -2.13 | -2.738 |+-------+-------+--------+--------+--------+--------+--------+===============================================================
数据集#1的结果与文献一致,即在单变量分析中,差异收益不显著,因为t值低于2.3,而在双变量分析中,差异收益在很大程度上是不显著的,因为t值低于2.3,表明市场体系风险因素不会提供超额回报。
# %% construct test_data for bivariate analysis# dataset 2from portfolio_analysis import Bivariate, Univariateimport numpy as np# select stocks whose size is among the up 30% stocks in each month and whose trading # days are more than or equal to 10 daystest_data_2 = return_company[(return_company['Ndaytrd']>=10)]test_data_2 = test_data_2[['emrwd', 'Msmvttl', 'beta', 'Date_merge']].dropna()test_data_2 = test_data_2[(test_data_2['Date_merge'] >= '2000-01-01') & (test_data_2['Date_merge'] <= '-12-01')]# Univariate analysisuni_2 = Univariate(np.array(test_data_2[['emrwd', 'beta', 'Date_merge']]), number=9)uni_2.summary_and_test()uni_2.print_summary_by_time()uni_2.print_summary()====================================================================================================+---------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+| Group | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Diff |+---------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+| Average | 0.008 | 0.012 | 0.013 | 0.016 | 0.016 | 0.015 | 0.017 | 0.015 | 0.014 | 0.012 | 0.004 || T-Test | 1.608 | 2.214 | 2.281 | 2.492 | 2.451 | 2.388 | 2.537 | 2.296 | 2.104 | 1.637 | 1.043 |+---------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+====================================================================================================# Bivariate analysisbi_2 = Bivariate(np.array(test_data_2), number=4)bi_2.average_by_time()bi_2.summary_and_test()bi_2.print_summary_by_time()bi_2.print_summary()===============================================================+-------+--------+--------+--------+--------+--------+--------+| Group | 1 | 2 | 3 | 4 | 5 | Diff |+-------+--------+--------+--------+--------+--------+--------+| 1 | 0.019 | 0.023 | 0.026 | 0.027 | 0.027 | 0.008 || | 2.657 | 3.184 | 3.538 | 3.44 | 3.017 | 2.203 || 2 | 0.011 | 0.014 | 0.015 | 0.017 | 0.016 | 0.004 || | 1.782 | 2.22 | 2.235 | 2.502 | 2.152 | 1.785 || 3 | 0.007 | 0.013 | 0.014 | 0.013 | 0.01 | 0.003 || | 1.236 | 2.23 | 2.122 | 1.89 | 1.505 | 1.379 || 4 | 0.008 | 0.01 | 0.009 | 0.011 | 0.009 | 0.001 || | 1.493 | 1.775 | 1.52 | 1.718 | 1.291 | 0.31 || 5 | 0.009 | 0.011 | 0.012 | 0.01 | 0.006 | -0.004 || | 1.916 | 1.919 | 1.887 | 1.556 | 0.846 | -1.035 || Diff | -0.01 | -0.012 | -0.014 | -0.017 | -0.021 | -0.011 || | -2.132 | -2.866 | -3.566 | -3.669 | -3.58 | -2.665 |+-------+--------+--------+--------+--------+--------+--------+===============================================================
数据集#2的结果与文献一致,即在单变量分析中,差异收益不显著,因为t值低于2.3,而在双变量分析中,差异收益在很大程度上不显著,因为t值低于2.3,表明市场体系风险因素不会提供超额回报。