Python3对股票的收益和风险进行分析

目录

一、股票收益率

1、股票的日收益率

(1)计算股票的日收益率

(2)绘制股票的日收益率的时间序列图

(3)日收益率均值计算

(4)日收益率的数据分布

(5)累计日收益率计算

2、股票的平均年化收益率

二、股票的风险性衡量

1、极差、四分位差、平均差、方差、标准差和离散系数计算

2、偏度

3、峰度

(1)峰度的计算

(2)峰度与正态分布的绘图比较

4、日收益率分布的正态性检验

5、股票的波动率计算


一、股票收益率

1、股票的日收益率

(1)计算股票的日收益率

日收益率计算公式如下:

该公式可理解为两天的价格差除以前一天的价格,下面提供两种方法计算日收益率。

第一种,在 pandas 中,使用 .pct_change() 方法来计算日收益率。

## 读取excel文件,并将‘日期’列解析为日期时间格式,并设为索引
stock_data=read_excel('stock_data/600000.SH.xlsx',parse_dates=['日期'],index_col='日期')
stock_data.drop('交易日期', axis=1, inplace=True) #删除第二列’交易日期
#对股票数据的列名重新命名
stock_data.columns=['open','high','low','close','volume','market_value','turnover','pe','pb']
stock_data.index.name='date' #日期为索引列
#将数据按日期这一列排序(保证后续计算收益率的正确性)
stock_data=stock_data.sort_values(by='date')
# 增加一列'earn_rate', 存储每日的收益率
stock_data['earn_rate'] = stock_data['close'].pct_change()
# 打印数据的前5行
print(stock_data.head())

第二种,直接按公式计算日收益率。

stock_data['earn_rate'] =(stock_data['close']-stock_data['close'].shift(1))/stock_data['close'].shift(1)
print(stock_data.head())

两种方法的结果相同,如下:

数据框增加了 earn_rate 一列,即股票的日收益率。注意第一天的收益率是缺失值 NaN,因为没有前一天的数据用于计算。为了后续计算方便,我们选取 earn_rate 这一列,并将缺失值丢弃,存储在新的变量 earn_rate_data中。使用 .dropna() 方法来删除缺失值。

earn_rate_data=stock_data['earn_rate'].dropna()
#打印earn_rate_data的前5行
print(earn_rate_data.head())

结果为:

 注意:计算对数收益率可以使你更好地了解回报随时间的增长。可以使用如下代码计算对数收益率:

stock_data['earn_rate']=np.log((stock_data['close']/stock_data['close'].shift(1)))

(2)绘制股票的日收益率的时间序列图

绘制股票从2013年到2019年的日收益率的时间序列图

earn_rate_data.plot(grid=True,color='green',label='600000.SH')
plt.title('2013-2019 earn rate of every day')
plt.ylabel('earn rate', fontsize='8')
plt.xlabel('date', fontsize='8')
#plt.ylim(0,0.3)  #可以绘制y轴的刻度范围
plt.legend(loc='best',fontsize='small')
plt.show()

(3)日收益率均值计算

均值是最常用的统计量,它将一串数据平均后浓缩为一个数值,但同时也丢失了数据波动性的信息。可使用 numpy 包中的 mean() 函数计算股票历史收益的均值。

# 计算股票的日平均收益
earn_mean_daily = np.mean(earn_rate_data)
print("日平均收益:", earn_mean_daily)

(4)日收益率的数据分布

绘制日收益率的直方图可了解其分布情况,同时也能观察到日收益率中的异常值。一般在收益分布的两侧有两条长长的尾巴,在投资时一般会尽量避免左侧尾巴上的异常值,因为他们代表了较大的亏损;而分布在右侧尾巴上的异常值通常是件好事,它代表较大的盈利。

使用 matplotlib 绘图包中的 hist()函数绘制直方图。

# 绘制直方图
plt.hist(earn_rate_data, bins=75)
plt.show()

其中,横轴表示日收益率,纵轴表示出现的次数(即频数)。

(5)累计日收益率计算

累积日收益率有助于定期确定投资价值。可以使用每日百分比变化的数值来计算累积日收益率,只需将其加上1并计算累积的乘积。累计日收益率计算并绘图代码如下:

stock_data['accumulate']=(1+stock_data['earn_rate']).cumprod()
stock_data['accumulate'].plot()
plt.legend()
plt.show()

 

2、股票的平均年化收益率

日收益率转换为年化收益率(一般假设一年252个交易日),其中μ是日平均收益率。

平均年化收益率计算公式如下:

earn_rate_year=(1+np.mean(earn_rate_data))**252-1
print("平均年化收益率:",earn_rate_year)

二、股票的风险性衡量

金融市场的风险是对不确定性的度量,反应在收益的波动上。一般可用以下统计量来表示:极差、四分位差、平均差、方差、标准差和离散系数;偏度;峰度等。

1、极差、四分位差、平均差、方差、标准差和离散系数计算

极差:极差为数据样本中的最大值与最小值的差值,是所有方式中最为简单的一种,它反应了数据样本的数值范围,是最基本的衡量数据离散程度的方式,受极值影响较大。

四分位差:即数据样本的上四分之一位和下四分之一位的差值,反应了数据中间50%部分的离散程度,其数值越小表明数据越集中,数值越大表明数据越离散,同时由于中位数位于四分位数之间,故四分位差也反应出中位数对于数据样本的代表程度,越小代表程度越高,越大代表程度越低。

平均差:各变量值与平均值的差的绝对值之和除以总数n,平均差以平均数为中心,能全面准确的反应一组数据的离散状况,平均差越大,说明数据离散程度越大,反之,离散程度越小。

方差:方差是各变量与平均值的差的平方和除以总数n-1,对数据离散程度的度量。

标准差:标准差又称均方差,是方差的算数平方根。投资回报中较高的标准差意味着较高的风险,因为数据分布离均值更远了,收益的波动幅度更大。方差与标准差都能很好的反应数据的离散程度。

离散系数:即变异系数,为一组数据的标准差与平均数之比。针对不同数据样本的标准差和方差,因数据衡量单位不同其结果自然无法直接进行对比,为出具一个相同的衡量指标,则进行了离散系数的计算。

日收益率极差、四分位差、方差、标准差和离散系数的计算如下:

earn_rate_range=np.max(earn_rate_data)-np.min(earn_rate_data)
earn_rate_interquartile_range=earn_rate_data.quantile(0.75)-earn_rate_data.quantile(0.25)
earn_rate_var=np.var(earn_rate_data)
earn_rate_std=np.std(earn_rate_data)
earn_rate_coefficient=np.std(earn_rate_data)/np.mean(earn_rate_data)
print("日收益率极差:",earn_rate_range)
print("日收益率四分位差: ",earn_rate_interquartile_range)
print("日收益率方差: ",earn_rate_var)
print("日收益率标准差: ",earn_rate_std)
print("日收益率离散系数: ",earn_rate_coefficient)

 将标准差乘以交易日数目的平方根,得到年化标准差。将年化标准差平方,就得到年化方差。即:年化收益率均值、年化收益率方差、年化收益率标准差和年化收益率离散系数计算如下:

earn_mean_year=(1+np.mean(earn_rate_data))**252-1
earn_var_year=np.std(earn_rate_data)**2*252
earn_std_year=np.std(earn_rate_data)*np.sqrt(252)
earn_coefficient_year=earn_std_year/earn_mean_year
print("年收益率均值:",earn_mean_year)
print("年收益率方差: ",earn_var_year)
print("年收益率标准差: ",earn_std_year)
print("年收益率离散系数: ",earn_coefficient_year)

2、偏度

偏度(skewness),是统计数据分布偏斜方向和程度的度量,是统计数据分布非对称程度的数字特征。定义上偏度是样本的三阶标准化矩

偏度衡量随机变量概率分布的不对称性,是相对于平均值下对称程度的度量。偏度为零表示数值相对均匀的分布在平均值的两侧,但不一定意味着一定是对称分布。

 

 偏度定义中包括正态分布(偏度=0),右偏分布(也叫正偏分布,其偏度>0),左偏分布(也叫负偏分布,其偏度<0)。

在金融领域,人们更倾向于正的偏度,因为这意味着高盈利的概率更大。可使用 scipy.stats 提供的 skew() 函数计算收益率分布的偏度,也可以直接使用pandas的函数。

from scipy import stats
# 计算收益分布的偏度
earn_rate_skew=stats.skew(earn_rate_data)
print("日收益率偏度:",earn_rate_skew)
print("日收益率偏度:",earn_rate_data.skew())

经过偏度的计算,可以看出它具有稍许的负偏度。

3、峰度

(1)峰度的计算

峰度(kurtosis)又称峰态系数。峰度表征概率密度分布曲线在平均值处峰值高低的特征数,反映了峰部的尖度。。随机变量的峰度计算方法为:随机变量的四阶中心矩与方差平方的比值减3。(减3是为了让正态分布的峰度为0)

这个统计量需要与正态分布相比较,峰度为0表示该总体数据分布与正态分布的陡缓程度相同;峰度大于0表示该总体数据分布与正态分布相比较为陡峭,为尖顶峰;峰度小于0表示该总体数据分布与正态分布相比较为平坦,为平顶峰。峰度的绝对值数值越大表示其分布形态的陡缓程度与正态分布的差异程度越大。

 下面公式也程为超值峰度:

在实际应用中,通常将峰度值做减3处理,使得正态分布的峰度0。因此,在使用统计软件进行计算时,应注意该软件默认的峰度值计算公式。如Eviews默认的正态分布峰度为3。

因为正态分布的峰度是3,所以将超出3的部分称为超值峰度。大部分金融收益都具有正的超值峰度。可以使用scipy.stats提供的 kurtosis() 函数计算分布的超值峰度,也可以使用pandas的函数。

from scipy import stats
# 计算收益分布的偏度
earn_rate_kurtosis=stats.kurtosis(earn_rate_data)
print("日收益率峰度:",earn_rate_kurtosis)
print("日收益率峰度:",earn_rate_data.kurt())

 上述峰度的计算结果表明,该股票日收益率的峰比正态分布高得多。

(2)峰度与正态分布的绘图比较

我们通过下图概率密度分布的比较看出来,图中橙色代表日收益率的分布,蓝色表正态分布。

# 模拟正态分布数据,其均值和标准差与文中的股票的日收益率相同。
mu=np.mean(earn_rate_data)
sigma=np.std(earn_rate_data)
norm=np.random.normal(mu,sigma,size=10000)
# 绘制正态分布的概率密度分布图
plt. hist(norm, bins=100, alpha=0.8, density=True, label='Normal Distribution')

# 绘制收益的概率密度分布图
plt.hist(earn_rate_data, bins=75, alpha=0.7, density=True,label='earn_rate Distribution')
plt.legend()
plt.show()

4、日收益率分布的正态性检验

首先,正态分布是对称的,其偏度为0,而该股票日收益率具有负的偏度-0.280;其次,正态分布的峰度是3,而该股票收益的峰度高达8.95。从这两个统计量看出,该股票日收益率并不是正态分布,它稍微向左偏斜,并且具有比较尖的峰。

为了判断股票收益分布的正态性,我们需要使用真正的统计检验方法,而不是简单地检查峰度或偏度。

这里使用 scipy.stats 提供的 shapiro() 函数,对股票收益分布进行 Shapiro-Wilk 检验。该函数有两个返回值,一个是检验的 t 统计量,另一个是 p 值。它越接近1就越表明数据和正态分布拟合得越好。

# 从 scipy.stats 导入shapiro
from scipy.stats import shapiro
# 对股票收益进行Shapiro-Wilk检验
shapiro_results = shapiro(earn_rate_data)
print("Shapiro-Wilk检验结果: ", shapiro_results)
# 提取P值
p_value = shapiro_results[1]
print("P值: ", p_value)

5、股票的波动率计算

股票的波动率衡量了股票在特定时间内收益率的变化。常常将一只股票的波动率和另一只股票比较,以寻找风险较小的股票;或是将之与市场指数比较,来检查股票在整个市场上的波动。

一般来说,波动率越高,该股票的投资风险更大,导致人们选择投资其他股票。

通过计算股票百分比变化的移动窗口标准差得到波动率。可以使用以下代码计算并绘图:

# 定义最小周期
min_periods = 75
# 计算波动率
vol = stock_data['earn_rate'].rolling(min_periods).std() * np.sqrt(min_periods)
# 绘制波动率曲线
vol.plot(grid=True)
# 显示绘图结果
plt.show()

 

注意:窗口的大小能够改变整体的结果:如果扩大窗口(也就是让min_periods变大),结果将变得不那么有代表性。如果缩小窗口,结果将更接近于标准差。考虑到所有这些,你会发现基于数据采样频率得到合适的窗口大小绝对是一项技能。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章