马科维茨的投资组合理论介绍(1)
这是现代投资组合理论的基础,CTA交易人员基本都要了解一下。
Harry Markowitz 在他 1952 年题为“投资组合选择”的论文中介绍了现代投资组合理论。他首先概述了投资组合选择是一个两步过程;首先,投资者必须考虑可用资产的未来表现(风险和回报),然后决定如何构建投资组合(即为每项资产分配多少钱)。
马科维茨专注于投资组合构建方面,并将预测未来表现这一更具投机性的任务留给了读者。事实上,在整篇论文中,回报都被假设遵循简单的高斯(正态)分布。这一假设是整个现代投资组合理论的基础,但也引起了很多批评,因为股票价格回报已被证明不遵循正态分布。
然而,其中依旧有很多有意义的深入的思考,一起了解为马科维茨赢得诺贝尔奖的数学理论。
我们的数据包含六只股票的每日回报,如下所示。回报范围为2000年初至2018年底。
![](https://miro.medium.com/v2/resize:fit:696/1*KodkSHicpsV319xOJGNWLA.png)
我们可以使用该数据中的两行代码立即获得预期年化回报、方差和协方差矩阵。我们注意到,通过使用这样的过去数据,我们假设未来将遵循过去的趋势。这在金融市场上是一个颇具争议的假设,但目前来说是可行的。
#-- Get annualised mean returns
mus = (1+daily_returns.mean())**252 - 1
#-- Get covariances and variances
#- Variance along diagonal of covariance matrix
#- Multiply by 252 to annualise it
#- https://quant.stackexchange.com/questions/4753/annualized-covariance
cov = daily_returns.cov()*252
获取投资组合
在不使用 numpy 以外的任何包的情况下,我们可以使用以下代码快速轻松地创建均值方差图。均值方差图使我们能够看到每个投资组合的风险和回报之间的权衡。
#- How many assests to include in each portfolio
n_assets = 5
#-- How many portfolios to generate
n_portfolios = 1000
#-- Initialize empty list to store mean-variance pairs for plotting
mean_variance_pairs = []
np.random.seed(75)
#-- Loop through and generate lots of random portfolios
for i in range(n_portfolios):
#- Choose assets randomly without replacement
assets = np.random.choice(list(daily_returns.columns), n_assets, replace=False)
#- Choose weights randomly
weights = np.random.rand(n_assets)
#- Ensure weights sum to 1
weights = weights/sum(weights)
#-- Loop over asset pairs and compute portfolio return and variance
#- https://quant.stackexchange.com/questions/43442/portfolio-variance-explanation-for-equation-investments-by-zvi-bodie
portfolio_E_Variance = 0
portfolio_E_Return = 0
for i in range(len(assets)):
portfolio_E_Return += weights[i] * mus.loc[assets[i]]
for j in range(len(assets)):
#-- Add variance/covariance for each asset pair
#- Note that when i==j this adds the variance
portfolio_E_Variance += weights[i] * weights[j] * cov.loc[assets[i], assets[j]]
#-- Add the mean/variance pairs to a list for plotting
mean_variance_pairs.append([portfolio_E_Return, portfolio_E_Variance])
我们使用以下公式计算预期回报:
\[ \operatorname{E}(R_p)=\sum_iw_i\operatorname{E}(R_i) \]
以及以下投资组合方差公式(包括协方差和个体方差):
\[ \sigma_p^2=\sum_i\sum_jw_iw_j\sigma_{ij} \]
使用我们生成的均值-方差对列表,我们现在可以绘制这些投资组合:
#-- Plot the risk vs. return of randomly generated portfolios
#- Convert the list from before into an array for easy plotting
mean_variance_pairs = np.array(mean_variance_pairs)
risk_free_rate=0 #-- Include risk free rate here for sharpe ratio
#-- Create Plot
fig = go.Figure()
fig.add_trace(go.Scatter(x=mean_variance_pairs[:,1]**0.5,
y=mean_variance_pairs[:,0],
#- Add color scale for sharpe ratio
marker=dict(color=(mean_variance_pairs[:,0]-risk_free_rate)/(mean_variance_pairs[:,1]**0.5),
showscale=True,
size=7,
line=dict(width=1),
colorscale="RdBu",
colorbar=dict(title="Sharpe<br>Ratio")
),
mode='markers'))
#- Add title/labels
fig.update_layout(template='plotly_white',
xaxis=dict(title='Annualised Risk (Volatility)'),
yaxis=dict(title='Annualised Return'),
title='Sample of Random Portfolios',
coloraxis_colorbar=dict(title="Sharpe Ratio"))
![](https://miro.medium.com/v2/resize:fit:696/1*j_tt69T3jsUAHyETemh4Xw.png)
在此图中,每个点代表一个投资组合。这里需要注意的是,这里显示的大多数投资组合都不在有效边界上。我们将在本文的下一部分中讨论这个问题。