Serving the Quantitative Finance Community

 
BuffaloFan32
Topic Author
Posts: 10
Joined: July 14th, 2016, 10:53 pm

Portfolio Optimization: Picking exactly n stocks from a universe of m

July 15th, 2016, 1:23 pm

I have been using Markowtiz efficient frontiers for a while to optimize portfolios (maximize expected value for least volatility in terms of standard deviation). Most of the time, that involves picking as many stocks as I want from a subset of stocks. Recently, I have been asked to optimize the same problem by using just 5 out of the total of a universe of 30. I could find the efficient frontier for all 30 choose 5 possible combinations and then pick the best looking one but that would be very computationally intensive. Are you aware of any methods for choosing the 5 best stocks out of a universe of 30 for given levels of expected return for the least amount of volatility at each point? I am not asking for the same 5 at each point but the best 5 for each given level of expected return.
 
User avatar
Alan
Posts: 3050
Joined: December 19th, 2001, 4:01 am
Location: California
Contact:

Re: Portfolio Optimization: Picking exactly n stocks from a universe of m

July 15th, 2016, 3:56 pm

Just thinking out loud, I assume your frontier calculator works with a "no short sale" constraint. So, an approximate solution might be to first toss out all the stocks, at a given level of expected return, that are pinned at weight 0. Then, if the remaining number is not too large (say 15), then running the optimizer 15 choose 5 ~ 3000 times might be quite feasible. Then move to the next level of expected return and repeat. 

Another approach might be simply brute force on the original 30 choose 5  ~ 142,506 problem with a very efficient c-code implementation. If you can get one run down to < 0.01 sec, which doesn't sound to hard to me, then it's only O(20) mins per level of expected return. 

Finally, if you have a nonlinear constrained optimizer, the problem is to add the additional constraint [$]\sum 1_{\{w_i > 0\}} = 5[$] to the problem, assuming you already have [$]w_i \ge 0[$] in there. In Mathematica, where I work, I would just experiment with NMinimize, adding that constraint and trying, say, the differential evolution method, and seeing if it converges to an answer: http://reference.wolfram.com/language/t ... #434989722
 
BuffaloFan32
Topic Author
Posts: 10
Joined: July 14th, 2016, 10:53 pm

Re: Portfolio Optimization: Picking exactly n stocks from a universe of m

July 15th, 2016, 5:20 pm

20 minutes?!?!  My code must be really inefficient because it takes me longer than .01 sec to draw an efficient frontier.  I have a routine that finds 50k points to optimize cost for a given level of risk and expected return that takes a few of hours to run.  I am using R.
 
User avatar
Alan
Posts: 3050
Joined: December 19th, 2001, 4:01 am
Location: California
Contact:

Re: Portfolio Optimization: Picking exactly n stocks from a universe of m

July 15th, 2016, 7:08 pm

Image
I just tried my last suggested method, modifying the code of the second answer here: 
http://mathematica.stackexchange.com/qu ... -of-stocks
This was for 10 choose 5 stocks. It seemed to run fine and produced the above frontier in about 100 secs. 
A check on the output shows that 5 weights were indeed exactly 0 at each expected return level.
(Note the example, before my modification, starts with the constraints [$]0 \le w_i \le 1[$]).

My modified code was:
newconstraint
If[w1>0,1,0]+If[w10>0,1,0]+If[w2>0,1,0]+If[w3>0,1,0]+If[w4>0,1,0]+
If[w5>0,1,0]+If[w6>0,1,0]+If[w7>0,1,0]+If[w8>0,1,0]+If[w9>0,1,0]==5

effFrontier2 = Table[{Sqrt[NMinimize[{portVar,Total[weights]==1 && portAverageReturns == i && 
newconstraint && And @@(0<=#<=1&/@weights)},weights,
Method->"DifferentialEvolution",MaxIterations->500][[1]]],i},{i,0.1,0.7,.1}]//Quiet
Perhaps you can port the thing to R.
 
BuffaloFan32
Topic Author
Posts: 10
Joined: July 14th, 2016, 10:53 pm

Re: Portfolio Optimization: Picking exactly n stocks from a universe of m

July 22nd, 2016, 11:35 pm

Thanks Alan! I will try to port that to R.