How can I implement a long-short-portfolio 130/30 with the Financial Toolbox?

10 views (last 30 days)
We are using LINPROG to do some Portfolio Optimization. Most of our portfolios are strictly long-term based, so there are no negative weights, hence lower bounds are set to 0. We specify the upper bounds, the non-equality constraints like sector membership and sector upper/lower bounds and then equality constraints so that all weights sum up equal to 1. We are wondering how to optimize in this environment a fixed long-short-portfolio, e.g. 130/30. One would have to differentiate if a share is long or short and then set all shorts such that the sum will be -30 and all longs in the way to be 130. But this is not really a equality constraint because you need to know all the shares which are long/short before optimizing to be able to set the two additional equality constraints to -1 and 0, which would sum up to -0.3, respectively 1 and 0 which sums up to 1.3.

Answers (1)

Chaitanya Chitale
Chaitanya Chitale on 18 Jan 2011
The key to handle this situation is to split the weights into "buys" (positive part) and "sells" (negative part). For example, assume the original linear program (LP) looks like this:
max c'*w
s.t.
Aw <= b
ones'*w = 1
0 <= w <= ub
Then, we need to let w = w_buy - w_sell, where w_buy and w_sell are complementary to each other, that is, they are both non-negative and only w_buy or _sell (both not both) can be non-zero. Complementarity constraints are hard to handle (more on this below). For this particular case, though, the value of w_buy and w_sell can be penalized in the objective to try to enforce complementarity. Specifically, the modified LP would look like this:
max c'*w - penalty * (ones'*w_buy + ones'*w_sell) s.t.
Aw <= b
w - w_buy + w_sell = 0
ones'*w_buy = 1.3
ones'*w_sell = 0.3
lb <= w <= ub
w_buy >= 0,
w_sell >= 0
Note that the "penalty" scalar in the objective promotes complementarity. So, if the optimal w(i) is 0.25, this penalization attempts to remove solutions like w_buy(i) = 0.26 and w_sell(i) = 0.01, and keeps only the solution with w_buy(i) = 0.25 and w_sell(i) = 0.
The objective function of the modified problem will be different from the optimal return, because it has the penalty terms. The optimal return needs to be computed after solving as c'*w.
Finding a good value for "penalty" may require some trial and error. There are some techniques to "guess" a good value, but for specific instances it's more practical to simply try different values (1, 10, 100,...). This value should be large enough to force w_buy or w_sell to 0, but it should not be too large or else numerical difficulties may arise.
Note that if after increasing "penalty" several times you still get the w_buy(i) = 0.26 and w_sell(i) = 0.01 solution, that may be because other constraints are getting in the way (e.g., some bounds may be forcing w_sell(i) to be > 0 to reach the required 0.3 selling quota). You may then want to relax some constraints and try again.
Note also that the constraint "ones'*w = 1" has been removed, because it is now redundant.
Also, note that the lower bounds on w need to be updated to allow short selling. Constraints on the total weights for different sectors (the "b" vector) may need to be modified as well, for the same reason.
A final note on complementarity: There are specialized algorithms to handle complementarity constraints (e.g., LCPROG). There are also ways to write them as non-linear constraints and use nonlinear optimization solvers (e.g., FMINCON). In either case, setting up the problem would require more work, and the resulting problem may be more difficult to solve.

Tags

No tags entered yet.

Community Treasure Hunt

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

Start Hunting!