Loading...
墨滴

傲天居士

2021/07/05  阅读:26  主题:默认主题

构建马科维茨投资组合

1. 马科维茨资产组合理论简介

证券及其它风险资产的投资首先需要解决的是两个核心问题:即预期收益与风险。 那么如何测定组合投资的风险与收益和如何平衡这两项指标进行资产分配是市场投资者迫切需要解决的问题。正是在这样的背景下,在50年代和60年代初,马科维茨理论应运而生。

该理论依据以下几个假设:

  1. 投资者在考虑每一次投资选择时,其依据是某一持仓时间内的证券收益的概率分布。
  2. 投资者是根据证券的期望收益率估测证券组合的风险。
  3. 投资者的决定仅仅是依据证券的风险和收益。
  4. 在一定的风险水平上,投资者期望收益最大;相对应的是在一定的收益水平上,投资者希望风险最小。

根据以上假设,马科维茨确立了证券组合预期收益、风险的计算方法和有效边界理论,建立了资产优化配置的均值-方差模型(允许放空):

若不允许放空,则为:

2. 实战操作

很多工具可以用于构建马科维茨资产组合。我们分别以VBA、MATLAB、R为例进行马科维茨资产组合的实战操作。

2.1 VBA

首先,Excel中有个solver规划求解器,可以解决规划问题。在构建马科维茨资产组合时,我们需要设置目标值、可变单元格以及约束条件。比如我们有5档股票,不允许无放空且每档股票的权重不能超过50%,那么我们需要勾选“使无约束变量为非负数”,并设置三个约束条件:

  1. 投资组合的期望收益约束条件
  2. 权重之和为1
  3. 权重不得超过50%

选择投资组合的标准差为目标函数,设置目标到最小值,并设置股票权重为可变单元格。每执行一次solver,即可在给定的投资组合期望收益下,求得满足约束条件的股票权重,进而求得投资组合的标准差与夏普比率。

然而,如果需要构建可行集,每次都要执行solver,显然工作量巨大。注意到这个过程虽然繁琐,但却是重复的,因此我们可以使用VBA自动调用solver,进行马科维茨资产组合与可行集的构建。

我们新建一个xlsm文件,事先进行名称定义等准备操作,如下图所示:

VBA代码如下所示:

Sub SolverMacro1(myObjFun, myChangeArea)
    Application.Run "SolverReset"
 '设置投资组合期望收益(期望收益单元格区域为H26,2表示等于,"c_"为事先定义的名称,对应某一存储给定期望收益的单元格区域)
    Application.Run "SolverAdd", "$H$26", 2, "c_"
 '
设置股票权重和为1(2表示等于)
    Application.Run "SolverAdd""$H$24", 2, "1"
 '设置可变单元格区域(可变单元格区域为股票权重,不超过50%,1表示小于等于)
    Application.Run "SolverAdd", myChangeArea, 1, "$H$30:$H$34"
 '
设置目标函数(目标函数为投资组合的标准差,设置目标到最小值)
    Application.Run "SolverOk", myObjFun, 2, "0", myChangeArea
    Application.Run "SolverSolve", True
End Sub
Sub solve()
    Set myObjFun = Application.InputBox(prompt:="请输入目标函数单元格", Type:=8)
    Set myChangeArea = Application.InputBox(prompt:="请输入可变单元格区域", Type:=8)
   
    For counter = 1 To 35
        Range("c_") = -0.005 + counter * 0.01
        SolverMacro1 myObjFun, myChangeArea
        Application.SendKeys ("{Enter}")
        Range("Result").Cells(counter, 1) = ActiveSheet.Range("c_")
        Range("Result").Cells(counter, 2) = ActiveSheet.Range("Portfolio_sigma")
        Range("Result").Cells(counter, 3) = ActiveSheet.Range("Portfolio_mean")
        Range("Result").Cells(counter, 4) = ActiveSheet.Range("Sharp_Ratio")
        Range("Result").Cells(counter, 5) = ActiveSheet.Range("x1_")
        Range("Result").Cells(counter, 6) = ActiveSheet.Range("x2_")
        Range("Result").Cells(counter, 7) = ActiveSheet.Range("x3_")
        Range("Result").Cells(counter, 8) = ActiveSheet.Range("x4_")
        Range("Result").Cells(counter, 9) = ActiveSheet.Range("x5_")
    Next counter
End Sub

执行VBA代码,可以绘制可行集:

2.2 R语言

我们首先选择5档股票:古井贡酒、光迅科技、科大讯飞、华联控股、英特集团。随后在R中进行操作。 R中有现成的工具包,可以非常方便地进行马科维茨资产组合的构建。代码如下:

rm(list = ls())
data <- load('sourcedata.Rdata')
data <- as.timeSeries(data,start=2016,freq=12)

# 构建投资组合可行集
library(fPortfolio)
Frontier <- portfolioFrontier(data,constraints = "LongOnly")
Frontier
Frontier1 <- portfolioFrontier(data,constraints = "ShortAllow")
Frontier1
plot(Frontier)
plot(Frontier1)

绘制出不可放空的条件下的可行集,如下图: 绘制出允许放空条件下的可行集,见下图:

2.3 MATLAB

构建马科维茨投资组合实际上是一个规划问题,MATLAB有现成的规划工具箱,既可以实现线性规划,又可以完成二次规划。我们分别以不允许放空、允许放空、不允许放空且单一资产的权重不超过0.5为例,在MATLAB中构建马科维茨资产组合。下面给出MATLAB构建马科维茨资产组合的演示代码:

clear all
clc
%读取变异数-共变异数矩阵
varmatrix=xlsread("myfile.xlsx",'Sheet1','Range1')
%读取历史平均报酬率
expected_return=xlsread("myfile.xlsx",'Sheet1','Range2')
%设置二次规划的部分参数
H=varmatrix*2;Aeq=zeros(2,5);Aeq(1,1:5)=expected_return;Aeq(2,1:5)=ones(1,5);
f=zeros(5,1);lb=zeros(5,1);ub=0.5*ones(5,1)

%不允许放空
X1=[];result_sigma1=[];result_return1=[];
%设置投资组合的要求报酬率
required_return1=[0.010;0.012;0.015;0.018;0.020;0.025;0.030;0.032;0.035;0.0367]
for i=1:10
    beq=[required_return1(i,1);1];
    
    [x1,fval,exitflag,output,lambda]=quadprog(H,f,[],[],Aeq,beq,lb)
    Return1=x1'*expected_return
    result_return1=[result_return1,Return1];result_sigma1=[result_sigma1,sqrt(fval)];X1=[X1,x1];
end
%允许放空
X2=[];result_sigma2=[];result_return2=[];
%设置投资组合的要求报酬率
required_return2=[0.010;0.015;0.020;0.025;0.030;0.035;0.040;0.045;0.050;0.060]
for i=1:10
    beq=[required_return2(i,1);1];
    [x2,fval,exitflag,output,lambda]=quadprog(H,f,[],[],Aeq,beq);
    Return2=x2'
*expected_return
    result_return2=[result_return2,Return2];result_sigma2=[result_sigma2,sqrt(fval)];X2=[X2,x2];
end
% 不允许放空且单一资产的权重不超过0.5
X3=[];result_sigma3=[];result_return3=[];
%设置投资组合的要求报酬率
required_return3=0.010:0.0005:0.032
for i=1:45
    beq=[required_return3(1,i);1];
    [x3,fval,exitflag,output,lambda]=quadprog(H,f,[],[],Aeq,beq,lb,ub);
    Return3=x3'*expected_return
    result_return3=[result_return3,Return3];result_sigma3=[result_sigma3,sqrt(fval)];X3=[X3,x3];
end

figure
plot(result_sigma1,result_return1,result_sigma2,result_return2,result_sigma3,result_return3);
xlabel('
sigma');ylabel('required return');
title('
Markowitz Portfolio')

下图表示马科维茨资产组合。其中序列data1表示不允许放空的情形,序列data2表示允许放空的情形,序列data3表示不允许放空且单一资产的权重不超过0.5的情形。 由上图可知,限制条件越多,资产组合的可行集越偏下。这一点与常识相吻合。

傲天居士

2021/07/05  阅读:26  主题:默认主题

作者介绍

傲天居士