马科维茨投资组合

2019-10-30 14:50:11 浏览数 (1)

学习一时爽,一直学习一直爽

  Hello,大家好,我是 もうり,一个从无到有的技术 语言小白。

https://blog.csdn.net/weixin_44510615/article/details/90377275

马科维茨投资组合

美国经济学家马科维茨(Markowitz)1952年首次提出投资组合理论(Portfolio Theory),并进行了系统、深入和卓有成效的研究,他因此获得了诺贝尔经济学奖。

该理论包含两个重要内容:均值-方差分析方法和投资组合有效边界模型。

在发达的证券市场中,马科维茨投资组合理论早已在实践中被证明是行之有效的,并且被广泛应用于组合选择和资产配置。但是,我国的证券理论界和实务界对于该理论是否适合于我国股票市场一直存有较大争议。

从狭义的角度来说,投资组合是规定了投资比例的一揽子有价证券,当然,单只证券也可以当作特殊的投资组合。

人们进行投资,本质上是在不确定性的收益和风险中进行选择。投资组合理论用均值—方差来刻画这两个关键因素。所谓均值,是指投资组合的期望收益率,它是单只证券的期望收益率的加权平均,权重为相应的投资比例。当然,股票的收益包括分红派息和资本增值两部分。所谓方差,是指投资组合的收益率的方差。我们把收益率的标准差称为波动率,它刻画了投资组合的风险。

人们在证券投资决策中应该怎样选择收益和风险的组合呢?这正是投资组合理论研究的中心问题。投资组合理论研究“理性投资者”如何选择优化投资组合。所谓理性投资者,是指这样的投资者:他们在给定期望风险水平下对期望收益进行最大化,或者在给定期望收益水平下对期望风险进行最小化。

因此把上述优化投资组合在以波动率为横坐标,收益率为纵坐标的二维平面中描绘出来,形成一条曲线。这条曲线上有一个点,其波动率最低,称之为最小方差点(英文缩写是MVP)。这条曲线在最小方差点以上的部分就是著名的(马考维茨)投资组合有效边界,对应的投资组合称为有效投资组合。投资组合有效边界一条单调递增的凸曲线。

如果投资范围中不包含无风险资产(无风险资产的波动率为零),曲线AMB是一条典型的有效边界。A点对应于投资范围中收益率最高的证券。

如果在投资范围中加入无风险资产,那么投资组合有效边界是曲线AMC。C点表示无风险资产,线段CM是曲线AMB的切线,M是切点。M点对应的投资组合被称为“市场组合”。

如果市场允许卖空,那么AMB是二次曲线;如果限制卖空,那么AMB是分段二次曲线。在实际应用中,限制卖空的投资组合有效边界要比允许卖空的情形复杂得多,计算量也要大得多。

在波动率-收益率二维平面上,任意一个投资组合要么落在有效边界上,要么处于有效边界之下。因此,有效边界包含了全部(帕雷托)最优投资组合,理性投资者只需在有效边界上选择投资组合。

回报率计算

100%* 7% 0% * 9%

标准差计算

assets = ['WMT', 'FB']


代码语言:javascript复制
import numpy as np
import pandas as pd
from pandas_datareader import data as wb
import matplotlib.pyplot as plt
%matplotlib inline
#宝洁 美国标普500强
assets = ['PG', '^GSPC']
pf_data = pd.DataFrame()
for a in assets:
    pf_data[a] = wb.DataReader(a,data_source='yahoo',start ='2010-1-1')['Adj Close']
代码语言:javascript复制
pf_data.tail()

PG

^GSPC

Date

2019-05-13

106.110001

2811.870117

2019-05-14

105.599998

2834.409912

2019-05-15

106.699997

2850.959961

2019-05-16

108.110001

2876.320068

2019-05-17

107.449997

2859.530029

代码语言:javascript复制
# 将第一个点变为100
(pf_data / pf_data.iloc[0] * 100).plot(figsize=(10, 5))

代码语言:javascript复制
# 对数收益率
log_returns = np.log(pf_data / pf_data.shift(1))
代码语言:javascript复制
log_returns.mean() * 250

代码语言:javascript复制
PG       0.092641
^GSPC    0.099800
dtype: float64
代码语言:javascript复制
log_returns.cov()*250

PG

^GSPC

PG

0.021227

0.011472

^GSPC

0.011472

0.022163

代码语言:javascript复制
log_returns.corr()

PG

^GSPC

PG

1.000000

0.528894

^GSPC

0.528894

1.000000


Create a variable that carries the number of assets in your portfolio.


代码语言:javascript复制
num_assets = len(assets)

代码语言:javascript复制
num_assets  #2

投资组合不需要等量加权。因此,创建一个称为“权重”的变量

。让它包含与投资组合中的资产一样多的随机生成的值。不要忘记这些值不应小于0,也不应等于或大于1

提示:有一个特定的numpy函数允许您生成这样的值。使用的方法-numpy.random.random()

在这里插入图片描述

代码语言:javascript复制
weights = np.random.random(num_assets)
# 将权重加起来等于1
weights /= np.sum(weights)
weights

代码语言:javascript复制
array([0.34968681, 0.65031319])

代码语言:javascript复制
weights[0]   weights[1]
代码语言:javascript复制
1.0

代码语言:javascript复制
# 组合的平均收益
np.sum(weights*log_returns.mean())*250

代码语言:javascript复制
0.09729653390436332

代码语言:javascript复制
# 组合的方差
np.dot(weights.T,np.dot(log_returns.cov()*250,weights))
代码语言:javascript复制
0.01718615078336416

代码语言:javascript复制
# 标准差
np.sqrt(np.dot(weights.T,np.dot(log_returns.cov()*250,weights)))
代码语言:javascript复制
0.13109596020993233

代码语言:javascript复制
# 模拟1000次

pfolio_returns =[]
pfolio_volatilities=[]
for x in range(1000):
    weights = np.random.random(num_assets)
    weights /= np.sum(weights)
    pfolio_returns.append(np.sum(weights*log_returns.mean())*250)
    pfolio_volatilities.append(np.sqrt(np.dot(weights.T,np.dot(log_returns.cov()*250,weights))))
pfolio_returns=np.array(pfolio_returns)
pfolio_volatilities=np.array(pfolio_volatilities)

代码语言:javascript复制
pfolio_returns[:10]
代码语言:javascript复制
array([0.09788039, 0.09297412, 0.09853974, 0.09620075, 0.09809919,
       0.09673725, 0.09541313, 0.09674151, 0.09610323, 0.09878069])

代码语言:javascript复制
pfolio_volatilities[:10]

代码语言:javascript复制
array([0.13379022, 0.14269733, 0.13795929, 0.12876705, 0.13504562,
       0.129451  , 0.12937429, 0.12945998, 0.12873816, 0.13976166])

代码语言:javascript复制
portfolios = pd.DataFrame({'Return':pfolio_returns,'Volatility':pfolio_volatilities})

代码语言:javascript复制
portfolios.head()

Return

Volatility

0

0.097880

0.133790

1

0.092974

0.142697

2

0.098540

0.137959

3

0.096201

0.128767

4

0.098099

0.135046


代码语言:javascript复制
portfolios.plot(x="Volatility",y ="Return",kind='scatter',figsize=(10,8))
plt.xlabel('Expected Volatility')
plt.ylabel('Expected Return')

代码语言:javascript复制
Text(0, 0.5, 'Expected Return')

0 人点赞