Fmincon given simple problem, not finding a solution

Hi,
I am having a weird problem where the fmincon functions works 1 second and on the second attempt, with the same inputs, it doesn't find a solution.
The problem I am trying to solve is I am trying to minimize the standard deviation of drifts betweens current and target weights of securities given an upper and lower bound.
Please let me know if I'm making any mistakes. Thanks
Inputs:
cashflow = -1134000;
current_target_weights = [0.0142023954819741,0.0150000000000000;0.0173447886267467,0.0175000000000000;0.0222995676451968,0.0225000000000000;0.0141407877584573,0.0150000000000000;0.0164172914902949,0.0175000000000000;0.00999573276025007,0.0100000000000000;0.00805550070703398,0.00750000000000000;0.0197716177594372,0.0200000000000000;0.0197493382178409,0.0200000000000000;0.0170298088271876,0.0175000000000000];
current_aum = 549922652;
Code:
% set current and target weights
current_weights = current_target_weights(:,1);
target_weights = current_target_weights(:,2);
% set current total values per security and add the cashflow at the end
current_navs = current_target_weights(:,1) .* current_aum;
current_navs(end + 1) = cashflow;
% set the new aum and get the new current weights (need to adjust current weights for the cash flow injection)
new_aum = current_aum + cashflow;
new_current_weights = current_navs ./ sum(new_aum);
% set the cash flow target to 0
target_weights(end + 1) = 0;
%calculate the drift between the target and current
drift = new_current_weights - target_weights;
%set lower and upper bounds.
if cashflow > 0
lower_bound = drift;
upper_bound = 0*new_current_weights; upper_bound(drift>0) = drift(drift>0);
elseif cashflow < 0
upper_bound = drift;
lower_bound = 0*new_current_weights; lower_bound(drift<0) = drift(drift<0);
end
%lock the cash flow bounds at 0 since we want to get rid of it
lower_bound(end) = 0;
upper_bound(end) = 0;
%set the optimization
Aeq = ones(1, length(new_current_weights))*sum(target_weights);
beq = sum(drift);
x0 = drift;
[x,fval,eflg] = fmincon(@(x)std(x),x0,Aeq,beq,[],[],lower_bound,upper_bound,[]);

8 个评论

Which MATLAB release are you using?
When I try that code on R2016a, I always seem to get the same result, with the message
[x,fval,eflg] = fmincon(@(x)std(x),x0,Aeq,beq,[],[],lower_bound,upper_bound,[])
Converged to an infeasible point.
fmincon stopped because the size of the current step is less than
the default value of the step size tolerance but constraints are not
satisfied to within the default value of the constraint tolerance.
That is, fmincon consistently indicates there is no solution.
I am using 2012b. I know that this error occurs, but I am just wondering why. The same code seems to work sometimes. I am wondering if there is a setting or something I can change so it works; for example, I don't need a lot of accuracy. It doesn't need to be 1e-16 accurary.
I installed R2012b on Windows 10 and tried your code, copying and pasting from what you posted above. Each time I tried, the result came out exactly the same, each time with the same output that implies there is no feasible solution.
Please recheck your code. You create Aeq and beq (equality constraints), but you pass them in the positions reserved for A and b (inequality constraints)
Hi Walter. Sorry, yes I wanted to see if it would work in either equality or inequality to find the solution. It should be an inequality.
I know it says there is no solution, but infact there is one. In manually doing it, if you did target_weights .* new_aum - current_weights .* current_aum, those are changes which it should calculate in percentage terms
Do you have a numeric solution for that particular problem? Do you have even one numeric solution that satisfies the constraints?
Hi,
Yes, I would hope for the output of x to be
[-0.000768257124602500;-0.000329180586560771;-0.000423578372517913;-0.000829992152425199;-0.00104878432325890;-0.000189708865714259;-0.000153833220027044;-0.000375056025958911;-0.000375100902519659;-0.000435001299370900;0;];
>> xsol = [-0.000768257124602500;-0.000329180586560771;-0.000423578372517913;-0.000829992152425199;-0.00104878432325890;-0.000189708865714259;-0.000153833220027044;-0.000375056025958911;-0.000375100902519659;-0.000435001299370900;0;];
Aeq*xsol <= beq
Aeq*xsol - beq
ans =
0
ans =
0.00443009306846424
Your proposed solution does not satisfy your constraints.
>> beq
beq =
-0.0052309731603196
>> Aeq*xsol
ans =
-0.000800880091855359

请先登录,再进行评论。

回答(1 个)

If you examine your lower_bound and upper_bound you will find that they are identical except at positions 6 and 7 (the positions where drift is positive). Those equalities force exact values for all the locations except 6 and 7.
If you substitute those exact values into the linear equation Aeq*X(:) <= beq then you can reduce it down to an equation in two variables, X(6) and X(7). You can solve for X(7) based upon the equation and the upper and lower bound constraints on X(6) . But you will find that the result is that X(7) = - X(6) - 213110080925339615/7493989779944505344 . X(6) is constrained to be non-negative, and any non-negative value you put in for X(6) will result in an negative value for X(7). But X(7) is constrained to be non-negative as well. You therefore have a contradiction. The constraints cannot be satisfied.
Operationally, you should try to write your code to directly put in the values where the upper and lower bound are forced to be equal. If you have the symbolic toolbox, you can put in the constraints symbolically and solve() the linear equality or linear inequality for the feasible regions, and you can then minimize std() over those regions... if you find any region at all.

1 个评论

Since X6 and X7 are so close to zero, I just manually set x6 to negative of what it is and yet the solver still does not find a solution ( I get rid of the contradiction)

请先登录,再进行评论。

类别

帮助中心File Exchange 中查找有关 Systems of Nonlinear Equations 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by