1

I am using quadprog link to find a portfolio of optimal weights.

So far, I have managed to implement a long only constraint (i.e. weights cannot be smaller than zero w >= 0 and w1 + w2 + ... wN = 1) as follows:

FirstDegree             = zeros(NumAssets,1);
SecondDegree            = Covariance;
Aeq                     = ones(1,NumAssets);
beq                     = 1;
A                       = -eye(NumAssets);
b                       = zeros(NumAssets,1);

x0                      = 1/NumAssets*ones(NumAssets,1);
MinVol_Weights          = quadprog(SecondDegree,FirstDegree,A,b,Aeq,beq,[],[],x0, options);

I am now tring to setup a short-only constraints, i.e. all the weights need to add up to -1 and they should be all strict smaller or equal to zero. How can this be rewritten?

WJA
  • 6,676
  • 16
  • 85
  • 152

1 Answers1

2

Note that you can rewrite any “greater than” inequality a ≥ b into a “less than” inequality -a ≤ -b by flipping signs. In your example, choose

Aeq = ones(1,NumAssets);
beq = -1;
A   = eye(NumAssets);
b   = zeros(NumAssets,1);

That means Aeq*w == w(1) + w(2) + … + w(NumAssets) == -1, and A*w <= 0 which is the same as saying w(i) <= 0 for all i.

Lumen
  • 3,554
  • 2
  • 20
  • 33
  • Works perfectly fine! – WJA Jan 25 '17 at 10:06
  • Might ask a follow up. How would you rewrite it to allow both positive and negative? Here is my thought: Aeq = ones(1,NumAssets); beq = 1; A = []; b = []; – WJA Jan 25 '17 at 10:53
  • You’re definitely right on the `A = []; b = [];` part. However, you cannot have that the weights add up to both 1 and –1 at the same time. Your `Aeq = ones(1,NumAssets); beq = 1;` means that they should add up to 1. If that’s what you intended, then go got it right. – Lumen Jan 25 '17 at 10:57
  • Hmm.. They don't need to add up to one per se. If they add up to -1 that is fine as well. So I guess I leave it [] then? – WJA Jan 25 '17 at 10:58
  • 1
    The absolute value is no linear function, unfortunately. So you cannot employ a constraint that says *“the sum of this should be equal to –1 or to +1“*. You could say *–1 ≤ Σ w_i ≤ 1* by `A = [eye(NumAssets); ones(1, NumAssets); -ones(1, NumAssets);` and `b = [zeros(NumAssets, 1); 1; 1];`, with `Aeq = []` and `beq = []`. – Lumen Jan 25 '17 at 12:02
  • Thanks for that. It didn't work though, gives me equal weights. I have re-posted it as a separate question here: http://stackoverflow.com/questions/41862287/how-to-allow-for-weights-between-1-and-1-using-constraints-in-aeq-x-beq – WJA Jan 25 '17 at 21:50