Python金融分析(八):正态性检验
引言
统计学,统计学,统计是一门科学吗?我觉得概率论应该是,但统计不是。
经济学,经济学,经济是一门科学吗?我觉得也不是,不过金工有点那个意思。
但是,不管怎么说,经济和金融中都少不了与统计打交道,而统计又是一个太广阔的领域了,所以我们从正态分布入手一窥究竟。
正态性检验
正态分布可以说是金融中最重要的一种分布,它之所以如此重要是因为现代金融中的大量模型,尤其是重要的一些模型都有赖于某些变量服从正态分布的假设:
-
投资组合理论(modern portfolio theory, MPT)
当股票收益率是正态分布时,可以用标准差衡量风险,从而找到一定收益率下风险最小的投资组合。
-
资本资产定价模型
当股票收益率服从正态分布时,单一股票的价格可以用β与市场指数联系起来。
-
有效市场假说
有效市场是价格反映所有可用信息的市场,如果这个假设成立,则股票价格随机波动,回报正态分布。
-
期权定价理论
布朗运动是金融工具随机价格变动建模的基准;例如,Black-Scholes-Merton期权定价公式使用几何布朗运动作为股票随时间价格波动的模型,价格服从对数正态分布,收益率服从正态分布。
-
……
美股示例
导入数据
为了检验真实的股票数据是否满足正态假设,我们选用两只科技股和两只ETF作为例子:
- AAPL,苹果公司股票价格
- MSFT,微软公司股票价格
- SPY, 标普500ETF
- GLD, SPDR黄金ETF
采用Yahoo Finance读取2010年以来的历史数据:
1 | %matplotlib inline |
1 | import math |
1 | stock_aapl = pddata.DataReader(name='AAPL', data_source='yahoo', |
1 | data = {'aapl': stock_aapl['Adj Close'], |
aapl | msft | spy | gld | |
---|---|---|---|---|
Date | ||||
2009-12-31 | 20.073631 | 24.241983 | 92.561058 | 107.309998 |
2010-01-04 | 20.386072 | 24.615801 | 94.130867 | 109.800003 |
2010-01-05 | 20.421322 | 24.623755 | 94.380074 | 109.699997 |
2010-01-06 | 20.096491 | 24.472631 | 94.446495 | 111.510002 |
2010-01-07 | 20.059338 | 24.218124 | 94.845207 | 110.820000 |
四只股票均以2009年12月31日的已调整收盘价=100作调整,作图:
1 | (data / data.iloc[0] * 100).plot(figsize=(15,9)) |
描述性统计
我们看一下四种证券对数收益率的直方图:
1 | log_returns = np.log(data / data.shift(1)) |
我个人的直观感受是微软和标普500ETF的对数收益率好像更符合正态分布一些,那么具体是不是呢?可以利用scipy.stats
模块进行描述性统计,得到初步的指标:
1 | import scipy.stats as scs |
1 | for sec in data.columns: |
Results for aapl
------------------------------
statistic value
------------------------------
size 2348.00000
min -0.13188
max 0.08502
mean 0.00100
std 0.01642
skew -0.27629
kurtosis 4.89598
Results for msft
------------------------------
statistic value
------------------------------
size 2348.00000
min -0.12103
max 0.09941
mean 0.00070
std 0.01445
skew -0.08792
kurtosis 6.58734
Results for spy
------------------------------
statistic value
------------------------------
size 2348.00000
min -0.06734
max 0.04929
mean 0.00049
std 0.00936
skew -0.48419
kurtosis 4.54397
Results for gld
------------------------------
statistic value
------------------------------
size 2348.00000
min -0.09191
max 0.04787
mean 0.00005
std 0.00991
skew -0.58841
kurtosis 5.94489
利用分位图可以更加直观地观察。分位图,即QQ图,是指一种通过比较两个概率分布的分位数对这两个概率分布进行比较的概率图方法从而检验数据的分布情况。我们知道服从正态分布的随机变量其仿射变化仍然服从正态分布,所以如果以标准正态分布的分位数为横坐标,待检验分布的分位值为纵坐标做分位图,就可以判断样本数据是否近似服从正态分布:如果否近似地在一条直线附近,图形是直线说明是正态分布,而且该直线的斜率为标准差,截距为均值。
此外,分位图也可以提供样本偏度和峰度的粗略信息。图形中有一段是直线,在两端存在弧度,则可说明峰度的情况。如果分位图中间部分是直线,但是右边在直线下面,左边在直线上面,说明分布的峰度大于3(超值峰度大于0),存在尖峰肥尾;反之说明峰度小于3,是薄尾。此外,如果图形是曲线图,说明不对称。
1 | import statsmodels.api as sm |
从图上可以看出来,实际上四种证券的对数收益率都不符合正态分布,存在明显的厚尾(从前面计算的峭度也可以看出来)。
正态性检验
scipy.stats
模块中有各种检验的方法,我们可以用skewtest()
、kurtosistest()
和normaltest()
分别对偏度、峰度和正态性进行假设检验,此处的原假设为偏度为0、峰度为3(超值峰度为0)及服从正态分布。当p值小于给定的置信水平时,则拒绝原假设。
1 | def normality_tests(arr): |
1 | for sec in data.columns: |
Results for aapl
------------------------------
Skew of data set -0.276
Skew test p-value 0.000
Kurt of data set 4.896
Kurt test p-value 0.000
Norm test p-value 0.000
Results for msft
------------------------------
Skew of data set -0.088
Skew test p-value 0.082
Kurt of data set 6.587
Kurt test p-value 0.000
Norm test p-value 0.000
Results for spy
------------------------------
Skew of data set -0.484
Skew test p-value 0.000
Kurt of data set 4.544
Kurt test p-value 0.000
Norm test p-value 0.000
Results for gld
------------------------------
Skew of data set -0.588
Skew test p-value 0.000
Kurt of data set 5.945
Kurt test p-value 0.000
Norm test p-value 0.000
从上面的结果可以看出,p值均为0,全部拒绝了原假设。说明这几种资产的对数收益率不服从正态分布,相应地,其价格也不适用几何布朗运动模型。因此。我们可能需要使用厚尾分布的模型( 例如,跳跃扩散模型或具有随机波动率的模型)。