[Returnanalytics-commits] r3041 - pkg/PortfolioAnalytics/R
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Tue Sep 10 16:51:47 CEST 2013
Author: rossbennett34
Date: 2013-09-10 16:51:46 +0200 (Tue, 10 Sep 2013)
New Revision: 3041
Modified:
pkg/PortfolioAnalytics/R/optFUN.R
Log:
Adding function to optFUN for proportional cost.
Modified: pkg/PortfolioAnalytics/R/optFUN.R
===================================================================
--- pkg/PortfolioAnalytics/R/optFUN.R 2013-09-10 00:56:37 UTC (rev 3040)
+++ pkg/PortfolioAnalytics/R/optFUN.R 2013-09-10 14:51:46 UTC (rev 3041)
@@ -587,3 +587,116 @@
# roi.result <- ROI_solve(x=opt.prob, solver="quadprog")
}
+# proportional transaction cost constraint
+gmv_opt_ptc <- function(R, constraints, moments, lambda, target, init_weights){
+ # function for minimum variance or max quadratic utility problems
+ # modifying ProportionalCostOpt function from MPO package
+
+ # Modify the returns matrix. This is done because there are 3 sets of
+ # variables 1) w.initial, 2) w.buy, and 3) w.sell
+ returns <- cbind(R, R, R)
+ V <- cov(returns)
+
+ # number of assets
+ N <- ncol(R)
+
+ # initial weights for solver
+ if(is.null(init_weights)) init_weights <- rep(1/ N, N)
+
+ # Amat for initial weights
+ Amat <- cbind(diag(N), matrix(0, nrow=N, ncol=N*2))
+ rhs <- init_weights
+ dir <- rep("==", N)
+ meq <- 4
+
+ # check for a target return constraint
+ if(!is.na(target)) {
+ # If var is the only objective specified, then moments$mean won't be calculated
+ if(all(moments$mean==0)){
+ tmp_means <- colMeans(R)
+ } else {
+ tmp_means <- moments$mean
+ }
+ Amat <- rbind(Amat, rep((1+tmp_means), 3))
+ dir <- c(dir, "==")
+ rhs <- c(rhs, (1+target))
+ meq <- 5
+ }
+
+ # Amat for positive weights for w.buy and w.sell
+ weights.positive <- rbind(matrix(0,ncol=2*N,nrow=N),diag(2*N))
+ temp.index <- (N*3-N+1):(N*3)
+ weights.positive[temp.index,] <- -1*weights.positive[temp.index,]
+ Amat <- rbind(Amat, t(weights.positive))
+ rhs <- c(rhs, rep(0, 2*N))
+
+ # Amat for full investment constraint
+ ptc <- constraints$ptc
+ Amat <- rbind(Amat, rbind(c(rep(1, N), (1+ptc), (1-ptc)), -c(rep(1, N), (1+ptc), (1-ptc))))
+ rhs <- c(rhs, constraints$min_sum, -constraints$max_sum)
+ dir <- c(dir, ">=", ">=")
+
+ # Amat for lower box constraints
+ Amat <- rbind(Amat, cbind(diag(N), diag(N), diag(N)))
+ rhs <- c(rhs, constraints$min)
+ dir <- c(dir, rep(">=", N))
+
+ # Amat for upper box constraints
+ Amat <- rbind(Amat, cbind(-diag(N), -diag(N), -diag(N)))
+ rhs <- c(rhs, -constraints$max)
+ dir <- c(dir, rep(">=", N))
+
+ # include group constraints
+ if(try(!is.null(constraints$groups), silent=TRUE)){
+ n.groups <- length(constraints$groups)
+ Amat.group <- matrix(0, nrow=n.groups, ncol=N)
+ for(i in 1:n.groups){
+ Amat.group[i, constraints$groups[[i]]] <- 1
+ }
+ if(is.null(constraints$cLO)) cLO <- rep(-Inf, n.groups)
+ if(is.null(constraints$cUP)) cUP <- rep(Inf, n.groups)
+ Amat <- rbind(Amat, cbind(Amat.group, Amat.group, Amat.group))
+ Amat <- rbind(Amat, cbind(-Amat.group, -Amat.group, -Amat.group))
+ dir <- c(dir, rep(">=", (n.groups + n.groups)))
+ rhs <- c(rhs, constraints$cLO, -constraints$cUP)
+ }
+
+ # Add the factor exposures to Amat, dir, and rhs
+ if(!is.null(constraints$B)){
+ t.B <- t(constraints$B)
+ Amat <- rbind(Amat, cbind(t.B, t.B, t.B))
+ Amat <- rbind(Amat, cbind(-t.B, -t.B, -t.B))
+ dir <- c(dir, rep(">=", 2 * nrow(t.B)))
+ rhs <- c(rhs, constraints$lower, -constraints$upper)
+ }
+
+ d <- rep(-moments$mean, 3)
+
+ qp.result <- try(solve.QP(Dmat=corpcor:::make.positive.definite(2*lambda*V),
+ dvec=d, Amat=t(Amat), bvec=rhs, meq=meq), silent=TRUE)
+ if(inherits(qp.result, "try-error")) stop("No solution found, consider adjusting constraints.")
+
+ wts <- qp.result$solution
+ w.buy <- qp.result$solution[(N+1):(2*N)]
+ w.sell <- qp.result$solution[(2*N+1):(3*N)]
+ w.total <- w.initial + w.buy + w.sell
+ # wts.final <- wts[(1:N)] + wts[(1+N):(2*N)] + wts[(2*N+1):(3*N)]
+
+ weights <- w.total
+ names(weights) <- colnames(R)
+ out <- list()
+ out$weights <- weights
+ out$out <- qp.result$val
+ return(out)
+
+ # TODO
+ # Get this working with ROI
+
+ # Not getting solution using ROI
+ # set up the quadratic objective
+ # ROI_objective <- Q_objective(Q=make.positive.definite(2*lambda*V), L=rep(-moments$mean, 3))
+
+ # opt.prob <- OP(objective=ROI_objective,
+ # constraints=L_constraint(L=Amat, dir=dir, rhs=rhs))
+ # roi.result <- ROI_solve(x=opt.prob, solver="quadprog")
+}
More information about the Returnanalytics-commits
mailing list