[Returnanalytics-commits] r2204 - in pkg/PortfolioAnalytics: R man sandbox
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Wed Jul 25 13:14:43 CEST 2012
Author: hezkyvaron
Date: 2012-07-25 13:14:43 +0200 (Wed, 25 Jul 2012)
New Revision: 2204
Modified:
pkg/PortfolioAnalytics/R/optimize.portfolio.R
pkg/PortfolioAnalytics/man/optimize.portfolio.Rd
pkg/PortfolioAnalytics/sandbox/testing_ROI.R
Log:
- updated the generalized ROI interface. The old ROI which uses constraint_ROI is "ROI_old", and the new generalized version is "ROI." There is still a bug that I am working out with optimize_method="ROI"
Modified: pkg/PortfolioAnalytics/R/optimize.portfolio.R
===================================================================
--- pkg/PortfolioAnalytics/R/optimize.portfolio.R 2012-07-25 07:03:07 UTC (rev 2203)
+++ pkg/PortfolioAnalytics/R/optimize.portfolio.R 2012-07-25 11:14:43 UTC (rev 2204)
@@ -33,10 +33,19 @@
#' DEoptim, and by default is the number of parameters (assets/weights) *10.
#'
#' itermax, if not passed in dots, defaults to the number of parameters (assets/weights) *50.
+#'
+#' The extension to ROI solves a limit type of convex optimization problems:
+#' 1) Maxmimize portfolio return subject box constraints on weights
+#' 2) Minimize portfolio variance subject to box constraints (otherwise known as global minimum variance portfolio)
+#' 3) Minimize portfolio variance subject to box constraints and a desired portfolio return
+#' 4) Maximize quadratic utility subject to box constraints and risk aversion parameter (this is passed into \code{optimize.portfolio} as as added argument to the \code{constraints} object)
+#' 5) Mean CVaR optiimization subject to box constraints and target portfolio return
+#' Lastly, because these closed-form optimizations are standardized, there is no need for a penalty term. Therefore, the \code{multiplier} argument in \code{\link{add.objective}} passed into the complete constraint object are ingnored by the solver.
+#' If you would like to interface with \code{optimize.portfolio} using matrix formulations, then use \code{ROI_old}.
#'
#' @param R an xts, vector, matrix, data frame, timeSeries or zoo object of asset returns
#' @param constraints an object of type "constraints" specifying the constraints for the optimization, see \code{\link{constraint}}, if using closed for solver, need to pass a \code{\link{constraint_ROI}} object.
-#' @param optimize_method one of "DEoptim", "random", "ROI","ROI_new", "pso". For using \code{ROI}, need to use a constraint_ROI object in constraints. For using \code{ROI_new}, pass standard \code{constratint} object in \code{constraints} argument. Presently, ROI has plugins for \code{quadprog}
+#' @param optimize_method one of "DEoptim", "random", "ROI","ROI_old", "pso". For using \code{ROI_old}, need to use a constraint_ROI object in constraints. For using \code{ROI}, pass standard \code{constratint} object in \code{constraints} argument. Presently, ROI has plugins for \code{quadprog} and \code{Rglpk}.
#' @param search_size integer, how many portfolios to test, default 20,000
#' @param trace TRUE/FALSE if TRUE will attempt to return additional information on the path or portfolios searched
#' @param \dots any other passthru parameters
@@ -49,7 +58,7 @@
optimize.portfolio <- function(
R,
constraints,
- optimize_method=c("DEoptim","random","ROI","ROI_new","pso"),
+ optimize_method=c("DEoptim","random","ROI","ROI_old","pso"),
search_size=20000,
trace=FALSE, ...,
rp=NULL,
@@ -242,7 +251,7 @@
} ## end case for random
- if(optimize_method == "ROI"){
+ if(optimize_method == "ROI_old"){
# This will take a new constraint object that is of the same structure of a
# ROI constraint object, but with an additional solver arg.
# then we can do something like this
@@ -252,10 +261,46 @@
out$weights <- weights
out$objective_measures <- roi.result$objval
out$call <- call
- } ## end case for ROI
+ } ## end case for ROI_old
- if(optimize_method == "ROI_new"){
+
+## The first draft of the integrated ROI:
+# if (optimize_method == "ROI") {
+# bnds <- list(lower = list(ind = seq.int(1L, N), val = constraints$min),
+# upper = list(ind = seq.int(1L, N), val = constraints$max))
+# objectives <- do.call(cbind, sapply(constraints$objectives,"[", "name"))
+# moments <- list()
+# for (i in 1:length(objectives)) moments[[i]] <- eval(as.symbol(objectives[i]))(R)
+# names(moments) <- objectives
+# plugin <- ifelse(any(objectives == "var"), "quadprog", "glpk")
+# target.return <- do.call(cbind, sapply(constraints$objectives,"[", "target"))
+# lambda <- do.call(cbind, sapply(constraints$objectives, "[", "risk_aversion"))
+# if (is.null(lambda)) lambda <- 1
+# if (plugin == "quadprog") ROI_objective <- ROI:::Q_objective(Q = 2 * lambda * moments$var, L = -moments$mean)
+# if (plugin == "glpk") ROI_objective <- ROI:::L_objective(L = -moments$mean)
+# Amat <- rbind(rep(1, N), rep(1, N))
+# dir.vec <- c(">=", "<=")
+# rhs.vec <- c(constraints$min_sum, constraints$max_sum)
+# if (!is.null(target.return)) {
+# Amat <- rbind(Amat, moments$mean)
+# dir.vec <- cbind(dir.vec, "==")
+# rhs.vec <- cbind(rhs.vec, target.return)
+# }
+# q.prob <- ROI:::OP(objective = ROI_objective,
+# constraints = L_constraint(L = Amat, dir = dir.vec, rhs = rhs.vec),
+# bounds = bnds)
+# roi.result <- ROI:::ROI_solve(x = q.prob, solver = plugin)
+# weights <- roi.result$solution
+# names(weights) <- colnames(R)
+# out$weights <- weights
+# out$objective_measures <- roi.result$objval
+# out$call <- call
+# }
+
+
+
+ if(optimize_method == "ROI"){
# This takes in a regular constraint object and extracts the desired business objectives
# and converts them to matrix form to be inputed into a closed form solver
# Applying box constraints
@@ -263,29 +308,44 @@
upper = list(ind = seq.int(1L, N), val = as.numeric(constraints$max)))
# retrive the objectives to minimize, these should either be "var" and/or "mean"
# we can eight miniminze variance or maximize quiadratic utility (we will be minimizing the neg. quad. utility)
- objectives <- do.call(cbind, sapply(constraints$objectives, "[", "name"))
- moments <- list()
- for(i in 1:length(objectives)) moments[[i]]<- eval(as.symbol(objectives[i]))(R)
- names(moments) <- objectives
- plugin <- ifelse(any(objectives=="var"), "quadprog", "glpk")
- target.return <- do.call(cbind,sapply(init.constr$objectives, "[", "target"))
- lambda <- do.call(cbind,sapply(init.constr$objectives, "[", "risk_aversion"))
- if(is.null(lambda)) lambda <- 1
+ moments <- list(mean=rep(0, N), var=NULL)
+ target <- NULL
+ lambda <- NULL
+ alpha <- 0.05
+ for(objective in constraints$objectives){
+ if(objective$enabled){
+ if(objective$name != "mean" || objective$name != "var" || objective$name != "CVaR")
+ stop("ROI only solves mean, var, or sample CVaR type business objectives,
+ choose a different optimize_method.")
+ moments[[objective$name]] <- eval(as.symbol(objective$name))(R)
+ target <- ifelse(!is.null(objective$target),objective$target, NA)
+ alpha <- ifelse(!is.null(objective$alpha), objective$alpha, alpha)
+ lambda <- ifelse(!is.null(objective$risk_aversion),objective$risk_aversion,1)
+ }
+ }
+ plugin <- ifelse(any(names(moments)=="var"), "quadprog", "glpk")
if(plugin == "quadprog") ROI_objective <- ROI:::Q_objective(Q=2*lambda*moments$var, L=-moments$mean)
if(plugin == "glpk") ROI_objective <- ROI:::L_objective(L=-moments$mean)
Amat <- rbind(rep(1, N), rep(1, N))
dir.vec <- c(">=","<=")
rhs.vec <- c(constraints$min_sum, constraints$max_sum)
- if(!is.null(target.return)) {
+ if(!is.na(target)) {
Amat <- rbind(Amat, moments$mean)
dir.vec <- cbind(dir.vec, "==")
- rhs.vec <- cbind(rhs.vec, target.return)
+ rhs.vec <- cbind(rhs.vec, target)
}
- q.prob <- ROI:::OP(objective=ROI_objective,
- constraints=L_constraint(L=Amat, dir=dir.vec, rhs=rhs.vec),
- bounds=bnds)
- roi.result <- ROI:::ROI_solve(x=q.prob, solver=plugin)
- weights <- roi.result$solution
+ if(any(names(moments)=="CVaR")) {
+ Rmin <- ifelse(is.na(target), 0, target)
+ ROI_objective <- ROI:::L_objective(c(rep(0,N), rep(-1/(alpha*T),T), -1))
+ Amat <- rbind(cbind(rbind(1,1,moments$mean)), matrix(0,nrow=3, ncol=T+1), cbind(R, diag(T), 1))
+ dir.vec <- c(">=","<=",">=",rep(">=",T))
+ rhs.vec <- c(constraints$min_sum, constraints$max_sum, Rmin ,rep(0, T))
+ }
+ opt.prob <- ROI:::OP(objective=ROI_objective,
+ constraints=ROI:::L_constraint(L=Amat, dir=dir.vec, rhs=rhs.vec),
+ bounds=bnds)
+ roi.result <- ROI:::ROI_solve(x=opt.prob, solver=plugin)
+ weights <- roi.result$solution[1:N]
names(weights) <- colnames(R)
out$weights <- weights
out$objective_measures <- roi.result$objval
@@ -293,9 +353,6 @@
} ## end case for ROI
-
-
-
## case if method=pso---particle swarm
if(optimize_method=="pso"){
stopifnot("package:pso" %in% search() || require("pso",quietly = TRUE) )
Modified: pkg/PortfolioAnalytics/man/optimize.portfolio.Rd
===================================================================
--- pkg/PortfolioAnalytics/man/optimize.portfolio.Rd 2012-07-25 07:03:07 UTC (rev 2203)
+++ pkg/PortfolioAnalytics/man/optimize.portfolio.Rd 2012-07-25 11:14:43 UTC (rev 2204)
@@ -3,7 +3,7 @@
\title{wrapper for constrained optimization of portfolios}
\usage{
optimize.portfolio(R, constraints,
- optimize_method = c("DEoptim", "random", "ROI", "ROI_new", "pso"),
+ optimize_method = c("DEoptim", "random", "ROI", "ROI_old", "pso"),
search_size = 20000, trace = FALSE, ..., rp = NULL,
momentFUN = "set.portfolio.moments")
}
@@ -17,11 +17,11 @@
need to pass a \code{\link{constraint_ROI}} object.}
\item{optimize_method}{one of "DEoptim", "random",
- "ROI","ROI_new", "pso". For using \code{ROI}, need to
- use a constraint_ROI object in constraints. For using
- \code{ROI_new}, pass standard \code{constratint} object
- in \code{constraints} argument. Presently, ROI has
- plugins for \code{quadprog}}
+ "ROI","ROI_old", "pso". For using \code{ROI_old}, need
+ to use a constraint_ROI object in constraints. For using
+ \code{ROI}, pass standard \code{constratint} object in
+ \code{constraints} argument. Presently, ROI has plugins
+ for \code{quadprog} and \code{Rglpk}.}
\item{search_size}{integer, how many portfolios to test,
default 20,000}
@@ -72,6 +72,25 @@
itermax, if not passed in dots, defaults to the number of
parameters (assets/weights) *50.
+
+ The extension to ROI solves a limit type of convex
+ optimization problems: 1) Maxmimize portfolio return
+ subject box constraints on weights 2) Minimize portfolio
+ variance subject to box constraints (otherwise known as
+ global minimum variance portfolio) 3) Minimize portfolio
+ variance subject to box constraints and a desired
+ portfolio return 4) Maximize quadratic utility subject to
+ box constraints and risk aversion parameter (this is
+ passed into \code{optimize.portfolio} as as added
+ argument to the \code{constraints} object) 5) Mean CVaR
+ optiimization subject to box constraints and target
+ portfolio return Lastly, because these closed-form
+ optimizations are standardized, there is no need for a
+ penalty term. Therefore, the \code{multiplier} argument
+ in \code{\link{add.objective}} passed into the complete
+ constraint object are ingnored by the solver. If you
+ would like to interface with \code{optimize.portfolio}
+ using matrix formulations, then use \code{ROI_old}.
}
\author{
Kris Boudt, Peter Carl, Brian G. Peterson
Modified: pkg/PortfolioAnalytics/sandbox/testing_ROI.R
===================================================================
--- pkg/PortfolioAnalytics/sandbox/testing_ROI.R 2012-07-25 07:03:07 UTC (rev 2203)
+++ pkg/PortfolioAnalytics/sandbox/testing_ROI.R 2012-07-25 11:14:43 UTC (rev 2204)
@@ -3,7 +3,6 @@
#
library(xts)
-library(quantmod)
library(quadprog)
library(Rglpk)
library(PerformanceAnalytics)
@@ -92,7 +91,15 @@
bounds=bnds)
mean.var.constr <- constraint_ROI(assets=funds, op.problem=mean.var.prob, solver="quadprog")
wts <- ROI_solve(x=mean.var.prob, solver="quadprog")$solution
-mean.var.solution <- optimize.portfolio(edhec, mean.var.constr, "ROI")
+mean.var.solution <- optimize.portfolio(edhec, mean.var.constr, "ROI_old")
+# using integrated ROI
+
+mean.var <- constraint(assets = colnames(edhec), min=-Inf, max =Inf, min_sum=1, max_sum=1, risk_aversion=1)
+mean.var <- add.objective(constraints=mean.var, type="return", name="mean", enabled=TRUE, multiplier=0, target=mu.port)
+mean.var <- add.objective(constraints=mean.var, type="risk", name="var", enabled=TRUE, multiplier=0)
+
+solution <- optimize.portfolio(edhec, mean.var, "ROI")
+paste(names(edhec),solution$weights)
# results for this are:
#
# > mean.var.solution$weights
More information about the Returnanalytics-commits
mailing list