今天学到数学模型P131 4.8节 例1 投资组合,这仍然是一个非线性规划问题,里面主要涉及两个式子。
其中第二个写起来比较复杂,在lingo中分步计算出期望,协方差后,比较好写。
model:
sets:
stock/1..3/:x,mean;
year/1..12/:;
link(stock,year):A,R;
matrix(stock,stock):cov;
endsets
data:
A=
1.3 1.103 1.216 0.954 0.929 1.056 1.038 1.089 1.09 1.083 1.035 1.176
1.225 1.29 1.216 0.728 1.144 1.107 1.321 1.305 1.195 1.39 0.928 1.715
1.149 1.26 1.419 0.922 1.169 0.965 1.133 1.732 1.021 1.131 1.006 1.908;
enddata
@for(link(i,j):@free(R(i,j)));!令R负数也可以;
@for(link(i,j):R(i,j)=A(i,j)-1);!计算年收益率;
@for(stock(i):mean(i)=@sum(year(j):R(i,j))/@size(year));!计算各股票年收益率均值(期望);
@for(matrix(i,j):cov(i,j)=@sum(year(k):(R(i,k)-mean(i))*(R(j,k)-mean(j)))/(@size(year)-1));!计算协方差矩阵;
min=@sum(matrix(i,j):x(i)*x(j)*cov(i,j));!年投资收益率方差最小;
@sum(stock(i):x(i)*mean(i))>=0.15;!股票综合年期望收益率不低于15%;
@sum(stock(i):x(i))=1;!股票权重;
end
结果跑出来和书上一致:
再用matlab用fmincon函数(解非线性规划)做一遍,先写目标函数,取名为minfun.m
function[y]=minfun(x)
global cv
y=[];
for i=1:3
for j=1:3
y=[y,x(i)*x(j)*cv(i,j)];
end
end
y=sum(y);
主程序:
clear all
global cv
profit=[1.3 1.103 1.216 0.954 0.929 1.056 1.038 1.089 1.09 1.083 1.035 1.176;
1.225 1.29 1.216 0.728 1.144 1.107 1.321 1.305 1.195 1.39 0.928 1.715;
1.149 1.26 1.419 0.922 1.169 0.965 1.133 1.732 1.021 1.131 1.006 1.908];
profit=profit-1;%年收益率要减1
ER=mean(profit,2); %求均值,每行为一个样本
cv=cov(profit'); %cov函数以每列为一个样本
% fmincon(@fun,x0,A,b,Aeq,beq,lb,ub,nonlcon(非线性约束),options) %求fun最小值,一般fval=fun(x)
%约束条件为Aeq*x = beq 和 A*x <= b
[x,fval]=fmincon('minfun',zeros(3,1),-ER',-0.15,ones(1,3),1) % x列向量,其他行向量
要注意一点,需要minfun函数和外面主程序都写global cv,才能顺利在minfun里调动cv变量(只写一个global cv 会出错,必须主程序里声明cv是全局变量,minfun函数里再次声明cv是全局变量,才能在minfun里调用cv)。还有一种方法是在minfun里将cv变量计算出来。
run出的结果: