金融学习之十四——使用Tushare获取数据计算投资组合的预期收益率和波动率

为了降低风险,投资者在购买股票时往往会构建一个投资组合,以对冲风险和最大获益。在投资组合中,描述该投资组合效果的两个重要变量是预期收益率及其波动率。
1.投资组合的预期收益率
预期收益率的计算公式为:
E(R)=E( ∑ k = 1 n w i R i \displaystyle \sum_{k=1}^n w_i R_i k=1nwiRi )= [   w 1 , w 2 , w 3 . . . w n [ \displaystyle \ w_1,w_2,w_3...w_n [ w1,w2,w3...wn ][   E ( R 1 ) , E ( R 2 ) , . . . E ( R n ) ] T \displaystyle \ E(R_1),E(R_2),...E(R_n)]^T  E(R1),E(R2),...E(Rn)]T
其中, w i w_i wi表示投资组合中第i支股票的权重,通常为股票市值占投资总值的比例,满足 ∑ k = 1 n w i = 1 \displaystyle \sum_{k=1}^n w_i =1 k=1nwi=1。而E( R i R_i Ri)表示第i支股票的预期收益率,通常用该股票过去的收益率均值表示。
假设我们任选5支股票(就拿Tushare里获取的前几支股票为例),计算其预期收益率。
首先获取所有股票的信息:

import tushare as ts
pro=ts.pro_api('b497571a3ddd7dde8ebe28b372879594b2f8356c918ad80dae01605b')  #此token已过期,只有基础积分,随便用
df = pro.stock_basic(exchange='', list_status='L', fields='ts_code,symbol,name,area,industry,list_date')
df.head()

在这里插入图片描述
为了简化操作,我们就选前5支数据较好的股票,先获取其行情数据,这里是收盘价close,日期为2018年7月1日至2021年8月31日:

dt=pd.DataFrame() #构建一个空数据框,装载所有股票行情信息
for i in df.loc[:5][['ts_code','name']].values:
    name=i[1]
    dt[name]=pro.daily(ts_code=i[0], start_date='20180701', end_date='20210831')['close']
dt

在这里插入图片描述
发现国华网安的数据后面有很多空数据,所以把它删掉,剩余5支作为待计算数据。

dt.drop('国华网安',axis=1,inplace=True)
dt

在这里插入图片描述
首先先做一个股票走势绘图:

from pylab import mpl
mpl.rcParams['font.sans-serif']=['SimHei']
mpl.rcParams['axes.unicode_minus']=False
(dt/dt.iloc[0]).plot(figsize=(10,8))    #所有数据都对首日数据进行归一处理

在这里插入图片描述
可以看到ST全新有点疯狂啊,而平安银行则有点萎靡不振。
接着对所有股票计算收益率,并绘制直方图。

r=np.log(dt/dt.shift(1))    #求收益率公式
r=r.dropna()     #去除其他有空数据的行
r.hist(bins=40,figsize=(10,8))

在这里插入图片描述
可以看到,除了ST全新,基本上收益率都还是比较符合正态分布的。
接着随机生成一个股票投资比例,计算一下,该投资组合的预期收益率:

#先求每支股票的年化平均收益率
r_mean=r.mean()*252
r_mean

结果是:
平安银行 -0.235112
万科A 0.054881
ST星源 0.063218
深振业A 0.072212
*ST全新 0.382847
dtype: float64

#然后随机生成投资比例,计算投资组合的预期收益率
import numpy as np
x=np.random.random(5)
weights=x/x.sum()
weights

得到各支股票的权重为:
array([0.13628201, 0.25905629, 0.12644307, 0.26794179, 0.21027683])
再计算组合投资收益率:

reward=np.sum(weights*r_mean)
reward

可以看到,这个组合的收益是0.056951510250772996,貌似刚刚跑赢CPI啊,基本上还是盈利的。

2.投资组合的波动率
波动率就是我们俗称的风险,用于反映收益率的波动程度。
考虑两支股票组合的收益率波动率,设 σ 1 \sigma_1 σ1, σ 2 \sigma_2 σ2分别是两支股票的波动率,则有组合波动率
σ 2 \sigma^2 σ2= w 1 2 σ 1 2 w_1 ^2 \sigma_1^2 w12σ12+ w 2 2 σ 2 2 w_2 ^2 \sigma_2^2 w22σ22+2 w 1 w 2 δ σ i σ 2 w_1 w_2 \delta \sigma_i\sigma_2 w1w2δσiσ2
这里的 δ \delta δ表示两支股票收益率的相关系数,并且与两支股票收益率的协方差有如下关系:
δ \delta δ=cov(R1,R2)/ σ i σ 2 \sigma_i\sigma_2 σiσ2
可见,若 δ \delta δ=1,即完全线性正相关,则组合波动率为 w 1 σ 1 + w 2 σ 2 w_1 \sigma_1 +w_2 \sigma_2 w1σ1+w2σ2,也就是加权平均值,若完全负相关,则为二者之差绝对值。
扩展到N支股票的组合中时(这公式实在太多了,懒得敲)
σ \sigma σ= w ∑ σ s w T \sqrt{w \displaystyle \sum \sigma_s w^T} wσswT
这里的 σ s \sigma_s σs表示投资组合的收益率协方差矩阵

接着我们继续计算投资组合的收益率波动率,首先对收益率计算协方差矩阵并年化处理:

r_cov=r.cov()*252
r_cov

再得到收益率相关系数矩阵,从相关系数看,相互之间,关联性较低

r_corr=r.corr()
r_corr

在这里插入图片描述
以及每支股票的年化波动率:

r_vol=r.std()*np.sqrt(252)
r_vol

可以看到,年化波动率都比较大
平安银行 0.350814
万科A 0.332052
ST星源 0.383830
深振业A 0.373611
*ST全新 0.591139
dtype: float64
最后,再根据前面的比例计算投资组合的波动率:

v_p=np.sqrt(np.dot(weights,np.dot(r_cov,weights.T)))
v_p

结果为0.23965157585238028,组合的波动率不小啊,应该是在ST全新上下注了不少的原因吧。
OK,全文到此结束,利用数据做了简单的预期收益率和波动率的计算,当然,这种方式得到的结果很随机,不一定能碰到最优解,因此后续将讨论如何取得最优解。

  • 8
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值