Skip to content

comparing solve.pq and nloptr for min variance portfolio

7 messages · Enrico Schumann, Alec Schmidt

#
I'm puzzled that I cannot reproduce results for asset weights using solve.pq and nloptr even in the case of just three assets.  E.g. if I use NLOPT_LD_SLSQP and start with initial weights of 1/3, I may obtain (0.47, 0, 0.53) vs (0.52, 0, 0.47).  If I start with  (0.52, 0, 0.47), I do get  (0.52, 0, 0.47)...

When I use NLOPT_GN_ISRES or other nloptr solvers that permit equality constraint sum(weights)=1 with initial weights of 1/3, I obtain (almost) the same initial weights after 20000 iterations with xtol_rel=1.0e-8...

I remember from my MC simulations of protein structures (20 years ago) that sampling is key due to multiple local minimums  but is it so bad for a simple portfolio?


I'll greatly appreciate relevant comments.

Alec
#
On Fri, 18 Mar 2016, Alec Schmidt <aschmid1 at stevens.edu> writes:
[...]

Unless your covariance matrix is 'broken' in some way, a
minimum-variance portfolio with only a budget constraint should be
fairly easy to compute (no multiple local minima, smooth objective
function, ...). Please provide a reproducible example.

Kind regards,
        Enrico
#
Hi Enrico,
Many thanks for your interest. I attach my script and input file with asset tickers. Sorry for lots of unrelated stuff - it's a working draft.

Alec
#
On Fri, 18 Mar 2016, Alec Schmidt <aschmid1 at stevens.edu> writes:
Thanks for sending the script, Alec. But you will need to
simplify it if people are to help you. [My bad: I should have
said _minimal_ reproducible example:
https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example
]

  
    
#
Enrico,
Here we're. I attach two scripts: one for solve.pq, another for nloptr. Both run with the same input file and print output on the screen.

Thanks again, Alec
1 day later
#
On Fri, 18 Mar 2016, Alec Schmidt <aschmid1 at stevens.edu> writes:
Hi Alec,

but these are still long programmes, which makes it hard to
figure out what exactly is wrong. For a start, I would not
compute the whole frontier, but concentrate on one point.

I computed the minimum-variance portfolio (without short
sales) with an alternative method, and it matches your
output for 'solve.QP'. So, one thing to check is your
implementation of the objective function for 'nloptr'.

Kind regards (and good luck)
     Enrico

  
    
2 days later
#
Hi  Enrico,
Indeed I had a bug in defining gradient. I attach the corrected script. But nloptr still needs resampling:

Say when I use the initial condition   x0<-rep(1/n, n), I get
        XLY XLF       XLV     Std.Dev  Exp.Return    sharpe
0.4957209   0 0.5042791 0.007334353 0.001318627 0.1797878

For x0<-c(0,1,0), I get
        XLY XLF       XLV     Std.Dev  Exp.Return    sharpe
0.4352796   0 0.5647204 0.007322604 0.001316634 0.1798041

For x0<-c(1,0,0), I get
       XLY XLF      XLV     Std.Dev  Exp.Return    sharpe
0.594686   0 0.405314 0.007378273 0.001321891 0.1791599

And finally for x0<-c(0,0,1), the  nloptr result 
        XLY          XLF       XLV     Std.Dev  Exp.Return    sharpe
0.4752062 3.665469e-19 0.5247938 0.007329077 0.001317951 0.1798249

practically coincides with that for solve.QP (with default initial condition) with max Sharpe value:
        XLY          XLF       XLV     Std.Dev  Exp.Return    sharpe
0.4752112 4.308351e-18 0.5247888 0.007329079 0.001317951 0.1798249

For other data samples (say for 2011-2013),  x0<-rep(1/n, n) may give the same result as solve.qp.

I wonder what is default initial condiiton in solve.qp and if nloptr sensitivity to initial conditions was ever discussed.

Best, Alec