[Returnanalytics-commits] r2117 - pkg/MPO/R
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Sat Jul 7 00:47:11 CEST 2012
Author: jamesleehobbs
Date: 2012-07-07 00:47:10 +0200 (Sat, 07 Jul 2012)
New Revision: 2117
Modified:
pkg/MPO/R/TurnoverOpt.R
Log:
-added long only option and added examples/plots
Modified: pkg/MPO/R/TurnoverOpt.R
===================================================================
--- pkg/MPO/R/TurnoverOpt.R 2012-07-06 17:16:23 UTC (rev 2116)
+++ pkg/MPO/R/TurnoverOpt.R 2012-07-06 22:47:10 UTC (rev 2117)
@@ -4,7 +4,7 @@
#todo: documentation with Roxygen2 and updating package dependecies
-TurnoverOpt <- function(returns,mu.target,w.initial,turnover){
+TurnoverOpt <- function(returns,mu.target,w.initial,turnover, long.only = FALSE){
nassets <- ncol(returns)
#using 3 sets of variabes...w.initial, w.buy, and w.sell
returns <- cbind(returns,returns,returns)
@@ -24,18 +24,29 @@
constraint.weights.initial <- rbind(diag(nassets),matrix(0,ncol=nassets,nrow=nassets*2))
#Make both w_buy and w_sell negative, and check that it is > the negative turnover
constraint.turnover <- c(rep(0,nassets),rep(-1,nassets),rep(1,nassets))
- constraint.weights.positive <-
+ constraint.weights.positive <-
rbind(matrix(0,ncol=2*nassets,nrow=nassets),diag(2*nassets))
temp.index <- (nassets*3-nassets+1):(nassets*3)
#need to flip sign for w_sell
- constraint.weights.positive[temp.index,]<-
+ constraint.weights.positive[temp.index,]<-
constraint.weights.positive[temp.index,]*-1
+
#put left hand side of constraints into constraint matrix
Amat <- cbind(constraint.sum, constraint.mu.target, constraint.weights.initial,
- constraint.turnover, constraint.weights.positive)
+ constraint.turnover, constraint.weights.positive)
#right hand side of constraints in this vector
bvec <- c(1,mu.target,w.initial,-turnover,rep(0,2*nassets))
-
+
+ #optional long only constraint
+ if(long.only == TRUE){
+ if ( length(w.initial[w.initial<0]) > 0 ){
+ stop("Long-Only specified but some initial weights are negative")
+ }
+ constraint.long.only <- rbind(diag(nassets),diag(nassets),diag(nassets))
+ Amat <- cbind(Amat, constraint.long.only)
+ bvec <- c(bvec,rep(0,nassets))
+ }
+
#Note that the first 5 constraints are equality constraints
#The rest are >= constraints, so if you want <= you have to flip
#signs as done above
@@ -46,19 +57,70 @@
w.sell <- solution$solution[(2*nassets+1):(3*nassets)]
w.total <- w.initial + w.buy + w.sell
achieved.turnover <- sum(abs(w.buy),abs(w.sell))
+ port.mu <- w.total%*%(mu[1:nassets])
+ list(w.initial = w.initial, w.buy = w.buy,w.sell=w.sell,
+ w.total=w.total,achieved.turnover = achieved.turnover,
+ port.var=port.var,port.mu=port.mu)
+}
+
+
+
+#TODO add documentation
+efrontMVTurnover <- function(returns,npoints = 10, minmu, maxmu,
+ w.initial,turnover,long.only = FALSE)
+{
+ p = ncol(returns)
+ efront = matrix(rep(0,npoints*(p+2)),ncol = p+2)
+ dimnames(efront)[[2]] = c("MU","SD",dimnames(returns)[[2]])
+ muvals = seq(minmu,maxmu,length.out = npoints)
+ for(i in 1:npoints) {
+ opt <- TurnoverOpt(returns,mu.target = muvals[i],w.initial,turnover,long.only)
+ efront[i,"MU"] <- opt$port.mu
+ efront[i,"SD"] <- sqrt(opt$port.var)
+ efront[i,3:ncol(efront)] <- opt$w.total
+ }
- list(w.initial = w.initial, w.buy = w.buy,w.sell=w.sell,
- w.total=w.total,achieved.turnover = achieved.turnover, port.var=port.var)
-}
+ efront
+}
-##example
-p = TurnoverOpt(large.cap.returns,mu.target=0.01,w.initial=rep(1/100,100),turnover=1)
-p
-sum(p$w.total)
-sum(p$w.initial)
-sum(p$w.buy)
-sum(p$w.sell)
+#long and short example
+data("Returns.RData")
+port.turn.10 <- efrontMVTurnover(large.cap.returns,npoints=20,minmu=0.001,maxmu=.1,
+ w.initial=rep(1/100,100),turnover=10)
+port.turn.2 <- efrontMVTurnover(large.cap.returns,npoints=20,minmu=0.001,maxmu=.05,
+ w.initial=rep(1/100,100),turnover=2)
+port.turn.1 <- efrontMVTurnover(large.cap.returns,npoints=20,minmu=0.001,maxmu=.025,
+ w.initial=rep(1/100,100),turnover=1)
+port.turn.05 <- efrontMVTurnover(large.cap.returns,npoints=20,minmu=0.001,maxmu=.016,
+ w.initial=rep(1/100,100),turnover=.5)
-wt<-p$w.total
-wt%*%cov(returns)%*%wt
+plot(x=port.turn.10[,"SD"],y=port.turn.10[,"MU"],type="l",
+ main="Efficent Frontiers with Turnover Constraints",xlab="SD",ylab="MU")
+lines(x=port.turn.2[,"SD"],y=port.turn.2[,"MU"],col="blue")
+lines(x=port.turn.1[,"SD"],y=port.turn.1[,"MU"],col="red")
+lines(x=port.turn.05[,"SD"],y=port.turn.05[,"MU"],col="orange")
+legend("topleft",bty="n",legend = c("Turnover 10","Turnover 2"
+ ,"Turnover 1","Turnover .5"), col=c("black",
+ "blue","red","orange"),lty=1)
+#long only example
+port.turn.long.10 <- efrontMVTurnover(large.cap.returns,npoints=20,minmu=0.001,maxmu=.020,
+ w.initial=rep(1/100,100),turnover=10,long.only=TRUE)
+port.turn.long.2 <- efrontMVTurnover(large.cap.returns,npoints=20,minmu=0.001,maxmu=.020,
+ w.initial=rep(1/100,100),turnover=2,long.only=TRUE)
+port.turn.long.1 <- efrontMVTurnover(large.cap.returns,npoints=20,minmu=0.001,maxmu=.015,
+ w.initial=rep(1/100,100),turnover=1,long.only=TRUE)
+port.turn.long.05 <- efrontMVTurnover(large.cap.returns,npoints=20,minmu=0.001,maxmu=.012,
+ w.initial=rep(1/100,100),turnover=.5,long.only=TRUE)
+
+plot(x=port.turn.long.10[,"SD"],y=port.turn.long.10[,"MU"],type="l",
+ main="Long-Only Efficent Frontiers with Turnover Constraints",xlab="SD",ylab="MU")
+lines(x=port.turn.long.2[,"SD"],y=port.turn.long.2[,"MU"],col="blue")
+lines(x=port.turn.long.1[,"SD"],y=port.turn.long.1[,"MU"],col="red")
+lines(x=port.turn.long.05[,"SD"],y=port.turn.long.05[,"MU"],col="orange")
+legend("topleft",bty="n",legend = c("Turnover 10","Turnover 2",
+ "Turnover 1","Turnover .5"), col=c("black",
+ "blue","red","orange"),lty=1)
+
+
+
More information about the Returnanalytics-commits
mailing list