参考代码
function portfolio
M = 1e6; % 总资金
n = 5; % 决策变量个数
lb = zeros(1,n); % 约束条件:xi >= 0
r = [5 28 21 23 25] / 100; % 平均收益率
q = [0 2.5 1.5 5.5 2.6] / 100; % 风险损失率
p = [0 1 2 4.5 6.5] / 100; % 交易费率
u = [0 103 198 52 40]; % 最低交易费
R = @(x) max(q.*x); % 目标函数
k = 8e4;
x0 = zeros(1,n);
x0(2) = M/(1+p(2));
% k = 0;
% x0 = [M zeros(1,n-1)];
warning off optim:fmincon:SwitchingToMediumScale
opt = optimset('MaxFunEvals',1e6,'TolX',1e-2,'TolCon',1e-2);
x = fmincon(R,x0,[],[],[],[],lb,[],@nlcon,opt);
num2str(x)
R(x)
[c,ce] = nlcon(x)
function [c,ce] = nlcon(x)
% 总盈利水平约束
c = k - sum( r.*x - max(p.*x,u.*(x~=0)) );
% 资金总量约束
ce = M - sum( x + max(p.*x,u.*(x~=0)) );
end
end
说明
1、这个不能算是线性规划问题,因为目标函数不是决策变量的线性函数,而约束条件由于存在最低交易费,也不是决策变量的线性函数(注:图中给出的两个约束条件都存在问题)。
2、优化结果很可能是局部最优,与初值有关。从现有数据看,初值选择有两种思路:
(1)低风险优先:全部存银行,但很可能由于达不到净收益k,而找不到可行解。
(2)高收益优先:从收益率和交易费率看,S1净收益最高,全部购买S1,但优化结果可能并非最优。例如取k=0,显然存银行风险最小,但优化结果并非如此。
3、有点奇怪,目标函数为什么不选择各种投资的风险之和,而是选择其中最大的呢?我觉得前者更合理,而又不会增加任何计算难度。
4、误差限的设置:TolX和TolCon如果用默认值1E-6,会由于数值计算误差而导致优化过程出现振荡,无法收敛。从现实情况考虑,无论投资还是收益,都不可能使用小于1分钱的单位,所以把误差限设为1E-2。
5、M、k未给出,这里任意指定。
希望对楼主有帮助,如果存在疑问欢迎探讨。
k是多少?