1998年全国大学生数学建模竞赛A题——投资的收益和风险数模P133|lingo,matlab

1998年全国大学生数学建模竞赛A题

目录

题目

问一

用lingo求解

用matlab求解

 问2


题目

市场上有n 种资产(如股票、债券、…)Si ( i=1,…n) 供投资者选择,某公司有数额为M 的一笔相当大的资金可用作一个时期的投资。公司财务分析人员对这n 种资产进行了评估,估算出在这一时期内购买Si 的平均收益率为 ri,并预测出购买Si的风险损失率为qi 。考虑到投资越分散,总的风险越小,公司确定,当用这笔资金购买若干种资产时,总体风险可用所投资的Si 中最大的一个风险来度量。

购买Si 要付交易费,费率为 pi,并且当购买额不超过给定值 ui时,交易费按购买ui 计算(不买当然无须付费)。另外,假定同期银行存款利率是r0, 且既无交易费又无风险。( r0=5% )

1)已知n = 4 时的相关数据如下:

Si    ri(%)  qi(%)  pi(%)  ui(元)   
S1   28     2.5     1         103
S2   21     1.5     2         198
S3   23     5.5     4.5       52
S4    25    2.6     6.5       40

试给该公司设计一种投资组合方案,即用给定的资金 ,有选择地购买若干种资产或存银行生息,使净收益尽可能大,而总体风险尽可能小。

2)试就一般情况对以上问题进行讨论,并利用以下数据进行计算。

Si ri/% qi/% pi/% ui/
S1 9.6 42 2.1 181
S2 18.5 54 3.2 407
S3 49.4 60 6 428
S4 23.9 42 1.5 549
S5 8.1 1.2 7.6 270
S6 14 39 3.4 397
S7 40.7 68 5.6 178
S8 31.2 33.4 3.1 220
S9 33.6 53.3 2.7 475
S10 36.8 40 2.9 248
S11 11.8 31 5.1 195
S12 9 5.5 5.7 320
S13 35 46 2.7 267
S14 9.4 5.3 4.5 328
S15 15 23 7.6 131


问一求解 

用lingo求解:

model:
sets:
type/1..5/:c,x;
rate/1..4/:;
link(type,rate):asset,A;
point/1..11/:w,q_lim,v_lim;
endsets
data:
asset=5 0 0 0
 28 2.5 1 103
 21 1.5 2 198
 23 5.5 4.5 52
 25 2.6 6.5 40;
w_start=0;
w_add=0.1;!权重初值和每次求解的增量;
enddata

submodel sub:
@for(type(i):c(i)=@if(x(i)#eq#0,0,@smax(A(i,3)*A(i,4),A(i,3)*x(i)))); !计算购买各资产的交易费;
q=@max(type(i):A(i,2)*x(i));          !投资组合x的风险(以各类资产中最大的风险为度量);
v=@sum(type(i):A(i,1)*x(i)-c(i));  !投资组合x的平均净利润;  
@sum(type(i):x(i)+c(i))=10000;          !约束条件; 
endsubmodel       

submodel obj:
min=w_sum*q-(1-w_sum)*v;
endsubmodel

calc:
@for(link(i,j)|j#le#3:A(i,j)=asset(i,j)*0.01);     !#le#左边运算符<=右边运算符;
@for(link(i,j)|j#eq#4:A(i,j)=asset(i,j));  
!系统参数设置;
!@set('terseo',1);!只输出简单的求解信息;
!@set('stawin',0);!关闭求解状态窗口;
!分别求解不同广告费上限的优化问题;
@for(point(n):w_sum=w_start+(n-1)*w_add;
              @solve(obj,sub);!求解子模型;
!记录计算结果;
             w(n)=w_sum;
             q_lim(n)=q;
             v_lim(n)=v;);
!显示所记录的结果;
@write('w   风险   净利润',@newline(1));!@write函数用于输出结果,@newline即输出新行;
@for(point(n):@write(@format(w(n),'#12.1f'),@format(q_lim(n),'#12.2f'),@format(v_lim(n),'#12.1f'),@newline(1)));
endcalc 

end

结果:

1998年全国大学生数学建模竞赛A题——投资的收益和风险数模P133|lingo,matlab_第1张图片

还可以对权重w按0.001的间隔取值计算并作图:

1998年全国大学生数学建模竞赛A题——投资的收益和风险数模P133|lingo,matlab_第2张图片

lingo:

sets:
type/1..5/:c,x;
rate/1..4/:;
link(type,rate):asset,A;
point/1..1001/:w,q_lim,v_lim;
endsets
data:
asset=5 0 0 0
 28 2.5 1 103
 21 1.5 2 198
 23 5.5 4.5 52
 25 2.6 6.5 40;
w_start=0;
w_add=0.001;!权重初值和每次求解的增量;
@ole('C:\Users\烟雨潇潇\Desktop\新建文件夹\CSDN\数模4.8例2.xlsx',q)=q_lim;
@ole('C:\Users\烟雨潇潇\Desktop\新建文件夹\CSDN\数模4.8例2.xlsx',v)=v_lim;
enddata

matlab:

clc,clear
q=xlsread('C:\Users\烟雨潇潇\Desktop\新建文件夹\CSDN\数模4.8例2.xlsx',1,'A1:A1000');
v=xlsread('C:\Users\烟雨潇潇\Desktop\新建文件夹\CSDN\数模4.8例2.xlsx',1,'B1:B1000');
plot(q,v)
xlabel('风险/元')
ylabel('收益/元')
title('例2的有效前沿')
grid on  %网格线

用matlab求解(失败):

主程序:

clear,clc
global w  %设定风险q和净收益v的权重分别为w,1-w
global asset
global type
%资产的数据矩阵,第一行为银行存款
%列1平均收益率,列2风险损失率,列3交易费率,列4定值
asset=[5 0 0 0;
 28 2.5 1 103;
 21 1.5 2 198;
 23 5.5 4.5 52;
 25 2.6 6.5 40];
asset(:,1:3)=asset(:,1:3)*0.01;%前三列用百分率
type=size(asset,1); %维度为1时,size返回矩阵的行数(资产种类)
% fmincon(@fun,x0,A,b,Aeq,beq,lb,ub,nonlcon(非线性约束),options)  %求fun最小值,一般fval=fun(x)
%约束条件为Aeq*x = beq 和 A*x <= b
x_final=zeros(type,11);%记录x
q=[];%记录投资组合x的风险
v=[];      %投资组合x的平均净收益
gs = GlobalSearch;
for i=1:11
    w=(i-1)/10;
    %[x,fval]=ga(@minfun,5,[],[],[],[],zeros(5,1),[],@nonfun);
    %x=x';
    problem = createOptimProblem('fmincon','objective',@minfun,'x0',zeros(5,1),'Aineq',[],'bineq',[],'Aeq',[],...
'beq',[],'lb',zeros(type,1),'ub',[],'nonlcon',@nonfun);
%'options',optimset('Algorithm','SQP','Disp','none')
    x = run(gs,problem);
    x_final(:,i)=x;
    q=[q,max(asset(:,2).*x)];
    v=[v,sum(asset(:,1).*x-cfun(x))];
end

minfun.m

function[y]=minfun(x)
global w
global asset
%x=x';
q=max(asset(:,2).*x);             %投资组合x的风险(以各类资产中风险最大的一个度量)
v=sum(asset(:,1).*x-cfun(x));      %投资组合x的平均净收益     
y=w*q-(1-w)*v;                    %设定风险q和净收益v的权重分别为w,1-w

cfun.m

function[c]=cfun(x)      %cfun函数计算购买各资产的交易费
global type
global asset
c=zeros(type,1);          %列向量
for i=1:type
    if x(i)<=0.06
        c(i,1)=0;
    else
        c(i,1)=max(asset(i,3)*asset(i,4),asset(i,3)*x(i));  %每种资产购买额x(i)不超过定值时,交易费按购买定值计算
    end
end

nonfun.m

function[g,ceq]=nonfun(x)%非线性约束:g(x)<=0 ,ceq(x)=0
%x=x';
g=[];
m=10000;
ceq=sum(x+cfun(x))-m;

matlab尝试过很多次,下图是最好的一次,但是cfun里要设置x<=0.06,x==0会和书上结果大不一样。

 

 问2

简单的代入就可以了,如果w以0.1为间隔,运行15秒即可出结果。

1998年全国大学生数学建模竞赛A题——投资的收益和风险数模P133|lingo,matlab_第3张图片

你可能感兴趣的:(lingo,matlab,数学建模)