python n个list如何组成矩阵_硬核科普系列:用python帮你建立自己的投资组合

111ed88325711437536ff9a0c75f0227.gif

听说金融量化很火,当一众金融大佬还在敲打excel的时候,编程技能树早就点满了的程序员是不是开始疯狂抖腿,跃跃欲试。所以小码想开一个硬核科普系列,和大家一起探索如何用python做投资分析。

43ef5744c71d3d6edd87c069cecdaebd.gif

今天的话题是如何建立投资组合。组成一个投资组合一般都要回答两个问题:1)投资什么 2)每个资产的比例是多少。

可能大部分人可能在主观上可以回答第一个问题,但对于每个资产的投资比例具体是多少,是否有一套可量化的方法在背后呢?小码今天就带大家用python套用经典的马科维兹-均值方差法来计算投资组合比例。

干货预警

warning,这篇文章会有大量干货!!

主要分为三个部分

1、 马科维兹的理论以及均值方差法是什么

2、 让我们用python来尝试一下

3、 理论的局限性

需要花大量时间理解理论部分的童鞋可以先暂且跳过第一部分直接看第二部分的实操。靴靴!

275d06be76ba683d98f6a00822188ba3.gif

马科维兹的理论以及均值方差法是什么 哈里马科维茨(Harry M. Markowitz),1927年8月24日生于美国伊利诺伊州。1952年,马科维茨在《金融杂志》上发表题为《资产组合选择——投资的有效分散化》一文,该文堪称现代金融理论史上的里程碑,标志着现代组合投资理论的开端。1990年他也因为这个理论获得诺贝尔经济学奖。 在这篇论文中马科维兹认为,在一定的前提下,可以利用股票的期望收益率和方差找到一条“有效边界”。这条“有效边界”代表着一定预期收益率下风险最小的组合,也代表着相同风险下,收益率最高的组合。 当然,这个理论有几个 非常重要的前提和假设 : 1、投资者都是 完全理性,并且厌恶风险 的 2、投资者做投资决策 只关心两件事:期望收益率和风险 。风险体现在证券的波动率,也就是方差上。投资者仅用这两个指标就可以做出投资决策。 3、 投资者 事先知道投资收益率的概率分布, 并且期望收益率满足正态分布的条件

组合的期望收益率

由于期望收益率满足正态分布,所以整个组合的期望收益率是组合里 每个资产的预期收益率的加权平均 ,权数是每个资产所占的比例。 举个例子: A股票的期望收益率为10%,B股票为5%。你的组合中A股票占比50%,B股票占比50%,则你的组合的期望收益率是10%*50%+5%*50%=7.5%。

5876eb25996b8ba4618cc95d0e120beb.png

组合的风险

正如假设的那样,组合的风险体现在收益率的波动性上。这里的波动性会有两个组成部分: 1)每个资产自身的收益率波动性(收益率的方差) 2)资产之间的联动性风险, 即资产之间的协方差。 对于每个资产来说,自身收益率的波动性(收益率的方差)越大,说明实际收益率偏离预期收益率幅度越大,风险就越高。 对于组合中任意两个资产来说(假如都是股票),他们股票价格的变动在一定程度上是有关联性的,因为他们不可避免会受到相同的外部系统风险的影响。 举个例子:沪深300指数下跌幅度很大的时候,通常大部分个股都也随之下跌,尽管下跌的幅度不同。协方差,或者相关系数就是用于判断这种价格变动趋势是否一致。

571ea95a2f872c2e9a5dad3832464e16.png

具体如何计算呢?以2个股票r1、r2组成的组合为例:

股票r的收益波动率:

0cb99a0fef6b10be319f2e7932c57eac.png

其中xi是股票的平均收益率,头上戴着帽子的x每天的股票收益率,n是天数

组合的波动率σp 等于:

7f36aa8436a623c2cff71f0e47f6c6cf.png

其中,w1是r1的所占比例,σ1是r1的收益率方差,w2是r2的所占比例,σ2是r2的收益率方差,cov(r1,r2)是r1和r2的协方差,也可以简写成σ12。具体的数学推导今天先不展开了~ 其实如果放在一个矩阵中会更清晰理解,这是一个2X2的,对角线对称的矩阵。 对角线分别是这两个 资产的方差 ,其余的部分是这两个资产的 协方差 。这个矩阵有个专业名词叫 协方差矩阵。

212e41c57804e5d93ba5c2c22d091e3b.png

如果是N个股票呢?

同样我们可以用一个NxN的协方差矩阵表示

75a8f04362c4073f1ba7853b7c0aec25.png

组合的波动率可以表示为:

9a764c7636b50f4265e0b7cec886873d.png

其中i,j表示N个资产中的任意两个资产,wi和wj分别是这两个资产的占比,σij是资产i和资产j的协方差。当i=j的时候,就是指代协方差矩阵中的对角线,也就是各个资产自身的方差。 了解了组合的期望收益率和组合风险的算法之后,你会发现, 如果你已经确定了组合里面要投资的资产,组合的期望收益率和风险就仅仅和每个资产的投资比例有关系, 因为资产的方差和资产间的协方差在你决定买什么资产的时候也已经确定下来了。 反过来说,如果我可以确定组合的期望收益率,那我是不是可以倒推出资产组合比例和组合的波动率?

62212198c5f4ef9ce82e50323e071910.png

让我们用python来尝试一下 主要分为5个步骤: 1)选择组合里的资产 2)计算每个资产每日的收益率  3)计算每个资产的期望收益率和组合的协方差矩阵  4)画出组合的有效边界  5) 解读和选择组合比例

第一步:选择组合里的资产

这里推荐大家使用一个免费的财经数据接口包 Tushare ,可以方便下载和分析金融数据。 这里小码选择了2020/4/3当天沪深300的前10大权重股,并且确保这些股票在2018/4/3至2020/4/3日这段时间内没有异常交易数据。最终小码选择了“民生银行”、“浦发银行”、“上海机场”、“宝钢股份'、'华夏银行'、'华能水电'、'华能国际'、'上港集团'、'浙能电力'、'白云机场'。股价选取的是2018/4/3至2020/4/3的每日收盘价。由于发现“包钢股份”的数据不完整,所以将第11名的“华能水电”代替了“包钢股份”。
%matplotlib inlineimport tushare as tsimport pandas as pdimport numpy as np#选出权重股,可自己调整前xx名hs300_top10=hs300.sort_values('weight',ascending=False)[:11] #select the first 11 biggst companyname_list=hs300_top10['name']names=name_list.tolist()codes=hs300_top10['code'].tolist()

先建立一个空的DataFrame,方便之后数据整合

#获取交易时间段,我这里选择了2018/04/03至2020/04/03两年期间dates=ts.get_hist_data('hs300',start='2018-04-03',end='2020-04-03').indexstocks=pd.DataFrame(columns=names,index=dates) #set up a empty dataframe

填入每日的股票价格数据

for i in range(0,10):    data=ts.get_hist_data(codes[i],start="2018-04-03",end="2020-04-03")['close']    stocks[names[i]]=data

b0717501dabf0bb3ea3336abe867a16e.png

第二步:计算每日的价格变动,即收益率

# Daily percent changes so periods = 1returns = stocks.pct_change(periods = 1)returns.dropna(inplace=True)

8001863cbfde5b255b3c99a2e93fe62f.png

第三步:计算每个资产的期望收益率和协方差矩阵

每个资产的期望收益率是是我预测的未来资产收益率,然而没有人能够准确预测。在实操的过程中,很多时候会用历史的平均值代替未来资产收益率的期望值。所以小码这里也”简单化“处理一下, 用过去两年的每日收益率平均值代替每个资产未来的期望收益率(更严谨的操作方式这边先不科普)

计算每个资产的期望收益率(年化)

assetReturns = returns.mean()#算出每个股票的历史平均收益率assetCovariance = returns.cov() #算出10个股票之间的协方差矩阵assetCorrelations = returns.corr() #算出10个股票之间的相关系numAsset=len(names)assetReturns * 250 #年化收益率assetCovariance*252 #年化协方差矩阵

年化收益率

e75ef7f317ab8b7598244716fb1e3862.png

年化协方差

4439ca33fc263a48f33be3c4e788d7fe.png

相关系数矩阵

c00dfb53bb1a77f78b5f74ccc84fb953.png

第四步:画出这个组合的有效边界

划重点,有效边界是马科维兹理论中的精华。他认为, 有效边界上的投资组合比例才是最优的投资比例。 先定义组合波动率、组合收益率和组合夏普比率的公式。 夏普比率代表投资人每多承担一分风险,可以拿到几分超额报酬。 假如夏普比率是2,说明投资者每承担1份的风险,可以收获2份的超额收益。

90c67e93ee2b2c8d36aaa7c8d0b4cf99.png

其中E(Rp):投资组合预期报酬率 Rf:无风险利率,例如国债收益率,是你不需要担心任何风险就能得到的投资回报率 σp:投资组合超额收益的标准差(即方差的算数平方根)
def portfolioVariance(weights): #计算组合方差    weights = np.array(weights)    var = np.dot(weights.T, np.dot(assetCovariance * 252, weights))    return vardef portfolioVolatility(weights): #计算组合标准差    return np.sqrt(np.dot(weights.T, np.dot(assetCovariance * 252, weights)))def portfolioReturn(weights): #计算组合的收益率    return np.sum(assetReturns * weights) * 252def portfolioSharpeRatio(weights): #计算组合夏普比率    return (portfolioReturn(weights) - rfr) / portfolioVolatility(weights)

先定义一些需要的参数

rfr = 0.015 #无风险利率,这里可变portfolioReturns = []portfolioVolatilies = []

导入SciPy.Optimize优化函数

import scipy.optimize as sco
利用scipy.optimize,我们可以算出不同的组合期望收益率对应的组合波动率、每个资产的比例和夏普比率。 我这里设定了一个限制:所有资产比例总和加起来要等于1,也就是说要求电脑算法100%利用所有的股票。
minRet = min(assetReturns*252)maxRet = max(assetReturns*252)trets = np.linspace(minRet, maxRet, 50)tvols = []weights=[]sharpe=[]initialWeights = np.ones(numAsset)bnds = tuple((0, 1) for x in initialWeights)for tret in trets:    cons = ({'type': 'eq', 'fun': lambda x:  portfolioReturn(x) - tret},            {'type': 'eq', 'fun': lambda x:  np.sum(x) - 1})    res = sco.minimize(portfolioVolatility, initialWeights, method='SLSQP', bounds=bnds, constraints=cons)    frontierWeights = res['x']    frontierRet = portfolioReturn(frontierWeights)    frontierVol = portfolioVolatility(frontierWeights)        tvols.append(res['fun'])    weights.append(frontierWeights)    sharpe.append((frontierRet-rfr)/frontierVol)

以组合期望收益率为y轴,组合波动率为x轴,画出有效边界

import matplotlib.pyplot as pltplt.figure(figsize=(16, 8))plt.scatter(tvols, trets, c=(trets-rfr) / tvols, marker='o')plt.grid(True)plt.xlabel('Expected volatility')plt.ylabel('Expected return')plt.colorbar(label='Sharpe ratio')

d926784c663b590abf85e5fe635793f0.png

第五步:解读和选择组合比例

上图中每个点,代表是一种投资比例得到的组合期望收益率(y轴)和组合波动率(x轴),右边的彩条显示的是夏普比率。 夏普比率越高,说明同等风险下获得的收益率越高。 在上面的图中可以看到有效边界上的组合夏普比率普遍高于0.8,而无效边界的夏普比率普遍低于0.8. 无效边界之所以是无效的,是因为在同等或者相似的风险下(波动率),可以找到更好的投资组合比例,使得组合收益率更高。 你可以尝试垂直x轴画一条线,这条垂线会和整条边界线有两个交点,一个在上面的有效边界上,一个在下面的无效边界上。有效边界上的交点代表的投资组合有更高的收益率,而且它的风险和无效边界上的组合是差不多的。 所以,对于理性的投资者,有效边界上的组合才是值得投资的。 根据在这个逻辑,我们还能发现一个 风险最小的组合 这个组合被马科维兹称为Global Minimum Variance Portfolio—— 全球最小方差组合 它为于整条边界线的 最左端

35c16f353e7181779591c6258bfb0f9b.png

红框部分便是GMV组合对应的投资比例

cce5e2ab89d7b72de06dd1cae2c68b40.png

可以筛选出夏普比率大于0.9的的投资组合

Sharpe_Ratio=pd.DataFrame(sharpe,columns=["Sharpe Ratio"])find_highest_ratio=Sharpe_Ratio[Sharpe_Ratio["Sharpe Ratio"]>=0.9].indexWeights=pd.DataFrame(weights,columns=names)Weights.loc[find_highest_ratio]

夏普比率大于0.9的的投资组合比例

7a74a4e854b935e988f4e77335ad996c.png

可以发现, 随着夏普比率越来越高,组合的集中度也越高,集中在收益率高的个股上 。而集中度高的组合,风险分散能力较低,组合的波动性也会比较大。所以,这是一个你需要权衡风险和收益率的决定。

a754a58dbfb06ff581ea71d3a2584cc2.gif

理论的局限性 20世纪50年代,马科维兹这个理论可谓是革命性的创新。因为他首次应用资产组合报酬的均值和方差这两个数学概念,从数学上明确地定义了投资者偏好。第一次将边际分析原理运用于资产组合的分析研究。但是这个理论也有 局限性 : 1、 现实的投资者并 不是完全理性 的; 2、 期望收益率以及波动率的预测有 非常高的误差 ,模型的参数稍有调整,输出的结果就有比较大的变动。比如,如果我不是用近两年的股价数据,而是用近三年的数据,那么有效边界的形状会有较大的变化;而且预测未来的收益率和波动率难度非常大 3、 股价在现实生活中 并不是正态分布的。 因此马科维兹的均值-方差法可以你决作为定组合比例的参考,但实际做投资决策的时候一定要谨慎哦。 往期推荐 支付宝跌破了2之后,我应该把钱放在哪里 2020-04-08 沪深300,你不能错过的黄金坑 2020-04-05 理财达人深度专访二:不要害怕“交学费” 2020-04-03 【粉丝福利】价值3999元的理财超级资料包免费送! 2020-03-30 小码福利时间 理财小白不懂投资,一手闲钱只能搁置? 小码为你打破此番窘境 史上最全“基金投资入门资料”免费送! 价值千元的入门书籍免费领! 详细操作步骤请看下图 da06f4ca73b0c7e412361c3a4b0985da.png b1a13c5e20e57c465e59da053293e0ec.png f30d4d2585e72baa381fb705bcb9b76c.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值