股票数据的正态性检验
数据的正态性统计检验在(十三)用SciPy模块进行概率分析和正态性检验中已经介绍得很详细,有四种方法,在此不再赘述。
QQ图的绘制
方法一
QQ图(quantile-quantile plot)在金融风险管理中的主要作用是检验两个数据是否服从同一分布,通过画出两组数据的累计分布函数,比较在同一百分比面积α下对应的x、y轴分位数是否相同(即QQ图所有点基本上在45°线上)来实现。比如我们很多时候需要检验股票价格数据是否服从对数正态分布,或者收益率是否服从正态分布。下面以2019年的上证指数收益率数据为例,画出它的累积分布函数图,以及与正态分布比较的QQ图来验证其正态性。第一步,获取上证指数收盘价数据:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import stats
from datetime import date
import pandas_datareader.data as web
from pylab import mpl
mpl.rcParams['font.sans-serif']=['SimHei']
mpl.rcParams['axes.unicode_minus']=False
data=web.DataReader('000001.SS','yahoo',start=date(2019,1,1),end=date(2020,1,1))
s=data['Adj Close'];s.head()
Out[3]:
Date
2019-01-02 2465.291016
2019-01-03 2464.363037
2019-01-04 2514.867920
2019-01-07 2533.089111
2019-01-08 2526.461914
Name: Adj Close, dtype: float64
第二步,生成上证指数收益率数据:
logre=s.pct_change()#简单收益率
logre=logre.dropna();logre.head()
Out[7]:
Date
2019-01-03 -0.000376
2019-01-04 0.020494
2019-01-07 0.007245
2019-01-08 -0.002616
2019-01-09 0.007078
Name: Adj Close, dtype: float64
dt=np.array(s)#转为array才能运算
logre2=pd.Series(np.log(dt[1:len(dt)]/dt[0:len(dt)-1]))#对数收益率
logre2.index=logre.index
logre2.head()
Out[8]:
Date
2019-01-03 -0.000376
2019-01-04 0.020287
2019-01-07 0.007219
2019-01-08 -0.002620
2019-01-09 0.007053
dtype: float64
第三步,用对数收益率数据画出其累积分布函数:
sorted_=np.sort(logre2*100)#对对数收益率排序
y=np.arange(len(sorted_))/float(len(sorted_))#生成纵轴坐标范围(0,1)
plt.plot(sorted_,y)
第四步,画QQ图,格式为scipy.stats.probplot(x, dist=‘norm’, plot=None),x是需要检验的数据:
#若只画上证指数分布的散点图(先求(0,1)之间的概率对应标准正态分布下的分位点):
#SH=stats.norm.ppf(y);plt.scatter(SH,sorted_)
#画上证指数分布的散点图、正态分布的分位点图构成的QQ图:
stats.probplot(sorted_,dist="norm",plot=plt)
很明显该分布不服从正态分布。从上述QQ图还可以发现,当该分布的分位点(纵轴)为-4时,对应正态分布的分位点大概是-2.5,也就是说该分布是左右肥尾的,画直方图验证一下:
logdf=pd.Series(npr.normal(0,1,241))
a=pd.concat([pd.Series(sorted_),logdf],axis=1)
a.columns=['上证指数样本','标准正态分布样本']
a=a.values#数据框转换为array数组
plt.figure(figsize=(8,6))
plt.hist(a,label=['上证指数样本','对数正态分布样本'],bins=100)
plt.xlabel('样本值')
plt.ylabel('频数')
plt.title('两分布抽样比较')
plt.legend()
plt.grid()
很明显上证指数的分布更胖、左右拖尾明显,是典型的尖峰厚尾数据。
方法二
seaborn库可以绘制带辅助线的直方图,statsmodels.api也有画QQ图的函数:
import pandas as pd
house=pd.read_csv('C:/Users/Desktop/house_price_gr.csv',encoding='gbk')
%matplotlib inline
import seaborn as sns
from scipy import stats
sns.distplot(house.rate,kde=True,fit=stats.norm)
import statsmodels.api as sm
import matplotlib.pyplot as plt
fig=sm.qqplot(house.rate,fit=True,line='45')
fig.show()
从房屋增长率的直方图和QQ图可以看到,增长率分布比较接近正态分布。
参考文献
https://blog.csdn.net/weixin_40076694/article/details/80048105