如何用MATLAB优化投资组合的风险(方差)或得到投资组合的有效前沿

两个资产画风险收益图Python 风险资产收益率的方差_投资组合

在金融领域,如果降低投资的风险是一个非常重要的问题,没有风险控制的投资无异于在资本的汪洋大海里裸奔。

我们一般用资产收益率的方差来表示资产的风险(资产收益率的标准差称为波动率), 而计算投资组合的风险则是一般人比较难理解的,这里我们不进行推导,直接给出计算表达式

两个资产画风险收益图Python 风险资产收益率的方差_两个资产画风险收益图Python_02


其中Var§为资产组合p的风险,w为各资产的权重,X为各个资产的收益率矩阵,Cov(X)为各资产收益率的协方差矩阵。

那么如何用MATLAB来优化投资组合的风险呢?我们采用优化的方法来实现,也即建立一个优化模型:

两个资产画风险收益图Python 风险资产收益率的方差_最小方差组合_03


两个资产画风险收益图Python 风险资产收益率的方差_两个资产画风险收益图Python_04


其中Z为目标函数(也即资产组合的方差),而w作为待优化的资产组合(也即各个资产的权重),rE为各个资产的预期收益率,rpE为我们设定的投资组合收益率。

clc;close all;clear all;warning off;%清除变量
 rand(‘seed’, 100);
 randn(‘seed’, 100);
 format long g;%% 1.读取数据和计算收益率,协方差等
 filename=‘投资组合股票日收益率.xls’;
 [adata201,bdata201,cdata201]=xlsread(filename);% 计算收益率
 price=adata201;
 stocknamecell=cdata201(1,2:end);
 figure;
 plot(price);
 legend(stocknamecell,‘fontname’,‘宋体’);
 xlabel(‘时间’,‘fontname’,‘宋体’);
 ylabel(‘资产价格’,‘fontname’,‘宋体’);
 title(’’,‘fontname’,‘宋体’);returns=price(2:end,:)./price(1:end-1,:)-1; % 收益率
figure;
 plot(returns);
 legend(stocknamecell,‘fontname’,‘宋体’);
 xlabel(‘时间’,‘fontname’,‘宋体’);
 ylabel(‘收益率’,‘fontname’,‘宋体’);
 title(’’,‘fontname’,‘宋体’);n=size(returns,2);% 资产数
 % 计算协方差
 mycov=cov(returns);
 retE=mean(returns);
 varE=var(returns);% 单项资产的方差=风险rmat=linspace(min(retE),max(retE),40)’;
 K=length(rmat);
 riskmat_noshort=zeros(K,1);
 riskmat_short=zeros(K,1);wait_hand = waitbar(0,‘running…’, ‘tag’, ‘TMWWaitbar’);
 for k=1:K% 每种收益率循环
 r=rmat(k);% 设定目标回报
 %% 2.fmincon函数优化投资组合
 A=[];
 b=[];
 ……
 lb=zeros(n,1);
 ub=ones(n,1);
 w0=ones(n,1)/n;
 opts=optimset(‘Display’,‘off’);% 不显示过程
 [w,fval]=fmincon(@(x) myobjfun(mycov,x),w0,A,b,Aeq,beq,lb,ub,[],opts);% 调用fmincon计算最小方差
 riskmat_noshort(k,1)=fval;
 %%
 A=[];
 b=[];
 ……
 lb=-1*ones(n,1);
 ub=ones(n,1);
 w0=ones(n,1)/n;
 opts=optimset(‘Display’,‘off’);% 不显示过程
 [w,fval]=fmincon(@(x) myobjfun(mycov,x),w0,A,b,Aeq,beq,lb,ub,[],opts);% 调用fmincon计算最小方差
 riskmat_short(k,1)=fval;
 waitbar(k/K,wait_hand);
 end
 delete(wait_hand);% 求最小方差组合
 %% 不允许卖空
 A=[];
 b=[];
 ……
 lb=zeros(n,1);
 ub=ones(n,1);
 w0=ones(n,1)/n;
 opts=optimset(‘Display’,‘off’);% 不显示过程
 [w_minrisk,fval_minrisk]=fmincon(@(x) myobjfun(mycov,x),w0,A,b,Aeq,beq,lb,ub,[],opts);% 调用fmincon计算最小方差
 disp(‘最小风险’);
 risk_min=fval_minrisk
 disp(‘最小风险时对应的收益率’);
 ret_minrisk=sum(w_minrisk’.*retE)
 disp(‘最小风险时对应的权重’);
 w_minriskfigure;
 hold on;
 plot(riskmat_short,rmat,‘b’,‘linewidth’,1);
 plot(risk_min,ret_minrisk,‘m.’,‘markersize’,30);
 plot(varE,retE,‘g.’,‘markersize’,25);
 legend({‘有效前沿’,‘最小方差组合’,‘单独资产’},‘fontname’,‘宋体’);
 xlabel(‘风险’,‘fontname’,‘宋体’);
 ylabel(‘收益率’,‘fontname’,‘宋体’);
 title(‘投资组合的有效前沿’,‘fontname’,‘宋体’);

程序结果:
最小风险

risk_min =

0.00117561007628918

最小风险时对应的收益率

ret_minrisk =

4.84661601286441e-05

最小风险时对应的权重

w_minrisk =

0.412535528609794
     0.285445046885802
     0.284734805971426
    0.0172846185329782


两个资产画风险收益图Python 风险资产收益率的方差_两个资产画风险收益图Python_05


两个资产画风险收益图Python 风险资产收益率的方差_最小方差组合_06


两个资产画风险收益图Python 风险资产收益率的方差_投资组合_07