为了降低风险,投资者在购买股票时往往会构建一个投资组合,以对冲风险和最大获益。在投资组合中,描述该投资组合效果的两个重要变量是预期收益率及其波动率。
1.投资组合的预期收益率
预期收益率的计算公式为:
E(R)=E(∑k=1nwiRi\displaystyle \sum_{k=1}^n w_i R_ik=1∑nwiRi )=[w1,w2,w3...wn[ \displaystyle \ w_1,w_2,w_3...w_n[w1,w2,w3...wn ][E(R1),E(R2),...E(Rn)]T\displaystyle \ E(R_1),E(R_2),...E(R_n)]^TE(R1),E(R2),...E(Rn)]T
其中,wiw_iwi表示投资组合中第i支股票的权重,通常为股票市值占投资总值的比例,满足∑k=1nwi=1\displaystyle \sum_{k=1}^n w_i =1k=1∑nwi=1。而E(RiR_iRi)表示第i支股票的预期收益率,通常用该股票过去的收益率均值表示。
假设我们任选5支股票(就拿Tushare里获取的前几支股票为例),计算其预期收益率。
首先获取所有股票的信息:
import tushare as tspro=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,日期为7月1日至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='0701', end_date='0831')['close']dt
发现国华网安的数据后面有很多空数据,所以把它删掉,剩余5支作为待计算数据。
dt.drop('国华网安',axis=1,inplace=True)dt
首先先做一个股票走势绘图:
from pylab import mplmpl.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()*252r_mean
结果是:
平安银行 -0.235112
万科A 0.054881
ST星源 0.063218
深振业A 0.072212
*ST全新 0.382847
dtype: float64
#然后随机生成投资比例,计算投资组合的预期收益率import numpy as npx=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=w12σ12w_1 ^2 \sigma_1^2w12σ12+w22σ22w_2 ^2 \sigma_2^2w22σ22+2w1w2δσiσ2w_1 w_2 \delta \sigma_i\sigma_2w1w2δσiσ2
这里的δ\deltaδ表示两支股票收益率的相关系数,并且与两支股票收益率的协方差有如下关系:
δ\deltaδ=cov(R1,R2)/σiσ2\sigma_i\sigma_2σiσ2
可见,若δ\deltaδ=1,即完全线性正相关,则组合波动率为w1σ1+w2σ2w_1 \sigma_1 +w_2 \sigma_2w1σ1+w2σ2,也就是加权平均值,若完全负相关,则为二者之差绝对值。
扩展到N支股票的组合中时(这公式实在太多了,懒得敲)
σ\sigmaσ=w∑σswT\sqrt{w \displaystyle \sum \sigma_s w^T}w∑σswT
这里的σs\sigma_sσs表示投资组合的收益率协方差矩阵
接着我们继续计算投资组合的收益率波动率,首先对收益率计算协方差矩阵并年化处理:
r_cov=r.cov()*252r_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,全文到此结束,利用数据做了简单的预期收益率和波动率的计算,当然,这种方式得到的结果很随机,不一定能碰到最优解,因此后续将讨论如何取得最优解。