This is a "not-so-easy" problem, since it involves non-linear constraints. I tried using langrangian multipliers, but even for very simple problems (eg linear objective function) it does not work so well. See an example below, where I try to obtain a long-short portfolio with a maximum exposure to a some "score". The optimal result should give weight 1/(maxL/2) to stocks in the long portfolio, and the opposite of that to the short names, but the procedure only gets somewhat close to that result (see plot).
Probably a genetic-algorithm approach ? la Burns works best in these cases...
nd<-100
scores<-sample(1:nd)
w<-array(0,nd)
mw<-0.2
maxL<-2
NetP<-0.0001
fnc<-function(x,score,l1,l2) {
sum(x*score)-l1*0.5*sum(x)^2 -l2*0.5*(sum(abs(x))-maxL)^2
}
l1<-0
l2<-0
w<-optim(w,fnc,NULL,method="L-BFGS-B",lower=-mw,upper=mw,control=list(fnscale=-1,maxit=10000),hessian=F,scores,l1,l2)$par
chk<-T
l1<-0
l2<-0
while(chk){
l1<-l1+200
out<-optim(w,fnc,NULL,method="L-BFGS-B",lower=-mw,upper=mw,control=list(fnscale=-1,maxit=10000),hessian=F,scores,l1,l2)
chk<-abs(sum(out$par))>NetP
w<-out$par
}
chk<-T
l2<-0
while(chk){
l2<-l2+200
out<-optim(w,fnc,NULL,method="L-BFGS-B",lower=-mw,upper=mw,control=list(fnscale=-1,maxit=10000),hessian=F,scores,l1,l2)
chk<-sum(abs(out$par))>maxL | abs(sum(out$par))>NetP
w<-out$par
}
round(out$par,4)
c(out$value,sum(out$par*scores))
c(l1,l2,out$counts)
c(out$convergence,out$message)
round(sum(out$par),6)
round(sum(abs(out$par)),6)
plot(sort(out$par))
Christian Prinoth
cp at epsilonsgr.it
+39-0288102355
-----Original Message-----
From: r-sig-finance-bounces at stat.math.ethz.ch
[mailto:r-sig-finance-bounces at stat.math.ethz.ch] On Behalf Of
guillaume.nicoulaud at halbis.com
Sent: Wednesday, 10 January, 2007 09:49
To: r-sig-finance at stat.math.ethz.ch
Subject: [R-SIG-Finance] solve.QP
Dear all,
I use solve.QP for Markowitz-like portfolio optimization
purposes and I am trying to set some basic constraints. So
far I have achieved to pass the followings:
- Sum of weights = desired target or band
- Target beta = anything I want
- Maximum individual weights (both long and short)
- Minimum individual weights if below 1/n (n being the number
of stocks in the investment universe)
And now here is what I would like to do:
- Setting a target number of non-zero weights (I want - say -
30 longs and shorts...)
- Setting a target gross exposure e.g. sum(abs(wi)) == 2
Does anybody has a piece of code I could adapt to do this? Is
there any other function that I could use with same level of
flexibility than solve.QP?
Thanks for your help!
G
Les informations contenues dans ce message sont
confidentielles et peuvent constituer des informations
privilegiees. Si vous n etes pas le destinataire de ce
message, il vous est interdit de le copier, de le faire
suivre, de le divulguer ou d en utiliser tout ou partie. Si
vous avez recu ce message par erreur, merci de le supprimer
de votre systeme, ainsi que toutes ses copies, et d en
avertir immediatement l expediteur par message de retour.
Il est impossible de garantir que les communications par
messagerie electronique arrivent en temps utile, sont
securisees ou denuees de toute erreur ou virus. En
consequence, l expediteur n accepte aucune responsabilite du
fait des erreurs ou omissions qui pourraient en resulter.
--- ----------------------------------------------------- ---
The information contained in this e-mail is confidential.\...{{dropped}}