-
Data Setup
+
+
Example 3
+
Data Setup
Here we will look at portfolio optimization in the context of portfolio of hedge funds.
- EDHEC-Risk Alternative Indexes
@@ -359,23 +350,19 @@
- Global Macro (GM)
-
-
Data
+
Data
R <- edhec[,c("Convertible.Arbitrage", "Equity.Market.Neutral",
"Fixed.Income.Arbitrage",
"CTA.Global", "Emerging.Markets", "Global.Macro")]
# Abreviate column names for convenience and plotting
colnames(R) <- c("CA", "EMN", "FIA", "CTAG", "EM", "GM")
-
-
Monthly Returns
+
Monthly Returns
-
-
Distribution of Monthly Returns
+
Distribution of Monthly Returns
-
-
Minimum Expected Shortfall
+
Minimum Expected Shortfall
Consider an allocation to hedge funds using the EDHEC-Risk Alternative Index as a proxy. This will be an extended example starting with an objective to minimize modified expected shortfall, then add risk budget percent contribution limit, and finally add equal risk contribution limit.
- Minimize Expected Shortfall
@@ -387,8 +374,7 @@
comments
-->
-
-
Specify Initial Portfolio
+
Specify Initial Portfolio
# Specify an initial portfolio
funds <- colnames(R)
portf.init <- portfolio.spec(funds)
@@ -410,8 +396,7 @@
basic comments about setting up an initial portfolio
-->
-
-
Add Objectives
+
Add Objectives
# Add objective to minimize expected shortfall
portf.minES <- add.objective(portf.init, type="risk", name="ES")
@@ -433,8 +418,7 @@
-->
-
-
Run Optimization
+
Run Optimization
# Combine the 3 portfolios
portf <- combine.portfolios(list(minES=portf.minES,
minES.RB=portf.minES.RB,
@@ -447,21 +431,18 @@
explain how portf is a list of portfolios and passed to optimize.portfolio
-->
-
-
Plot in Risk-Return Space
+
Plot in Risk-Return Space
-
-
Chart Risk Budgets
+
Chart Risk Budgets
chart.RiskBudget(opt.minES[[2]], main="Risk Budget Limit",
risk.type="percentage", neighbors=10)
chart.RiskBudget(opt.minES[[3]], main="Equal ES Component Contribution",
risk.type="percentage", neighbors=10)
-
-
Set Rebalancing Parameters and Run Backtest
+
Set Rebalancing Parameters and Run Backtest
# Set rebalancing frequency
rebal.freq <- "quarters"
@@ -478,17 +459,13 @@
trailing_periods=trailing,
search_size=5000,
traceDE=0)
-
-
Min ES Risk Contributions and Weights Through Time
+
Min ES Risk Contributions and Weights Through Time
-
-
Min ES Risk Budget Limit Risk Contributions and Weights Through Time
+
Min ES Risk Budget Limit Risk Contributions and Weights Through Time
-
-
Min ES Equal Component Contribution Risk Contributions and Weights Through Time
[TRUNCATED]
To get the complete diff run:
svnlook diff /svnroot/returnanalytics -r 3365
From noreply at r-forge.r-project.org Mon Apr 14 23:09:50 2014
From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org)
Date: Mon, 14 Apr 2014 23:09:50 +0200 (CEST)
Subject: [Returnanalytics-commits] r3366 - pkg/PortfolioAnalytics/man
Message-ID: <20140414210950.A926B183A10@r-forge.r-project.org>
Author: rossbennett34
Date: 2014-04-14 23:09:50 +0200 (Mon, 14 Apr 2014)
New Revision: 3366
Modified:
pkg/PortfolioAnalytics/man/PortfolioAnalytics-package.Rd
Log:
Updates to package Rd file. Minor edits and adding package dependencies section.
Modified: pkg/PortfolioAnalytics/man/PortfolioAnalytics-package.Rd
===================================================================
--- pkg/PortfolioAnalytics/man/PortfolioAnalytics-package.Rd 2014-04-14 01:59:38 UTC (rev 3365)
+++ pkg/PortfolioAnalytics/man/PortfolioAnalytics-package.Rd 2014-04-14 21:09:50 UTC (rev 3366)
@@ -7,39 +7,63 @@
}
\description{
-\kbd{PortfolioAnalytics} provides an \R packaged to provide numerical solutions for portfolio problems with complex constraints and objective sets. The goal of the package is to aid practicioners and researchers in solving portfolio optimization problems with complex constraints and objectives that mirror real-world applications.
+\kbd{PortfolioAnalytics} is an \R package to provide numerical solutions for portfolio problems with complex constraints and objective sets. The goal of the package is to aid practicioners and researchers in solving portfolio optimization problems with complex constraints and objectives that mirror real-world applications.
-One of the goals of the packages is to provide a common interface to specify constraints and objectives that can be solved by any supported solver (i.e. optimization method). Currently supported optimization methods include random portfolios, differential evolution, particle swarm optimization, generalized simulated annealing, and linear and quadratic programming routines. Additional information on random portfolios is provided below. The differential evolution algorithm is implemented via the \kbd{DEoptim} package, the particle swarm optimization algorithm via the \kbd{pso} package, the generalized simulated annealing via the \kbd{GenSA} package, and linear and quadratic programming are implemented via the \kbd{ROI} package which acts as an interface to the \kbd{Rglpk} and \kbd{quadprog} packages.
+One of the goals of the packages is to provide a common interface to specify constraints and objectives that can be solved by any supported solver (i.e. optimization method). Currently supported optimization methods include
+\itemize{
+ \item random portfolios
+ \item differential evolution
+ \item particle swarm optimization
+ \item generalized simulated annealing
+ \item linear and quadratic programming routines
+}
-A key strength of \kbd{PortfolioAnalytics} is the generalization of constraints and objectives that can be solved. The quadratic and linear programming solvers can solve a limited type of convex optimization problems.
+The solver can be specified with the \code{optimize_method} argument in \code{optimize.portfolio} and \code{optimize.portfolio.rebalancing}. The \code{optimize_method} argument must be one of "random", "DEoptim", "pso", "GenSA", "ROI", "quadprog", "glpk", or "symphony".
+
+Additional information on random portfolios is provided below. The differential evolution algorithm is implemented via the \kbd{DEoptim} package, the particle swarm optimization algorithm via the \kbd{pso} package, the generalized simulated annealing via the \kbd{GenSA} package, and linear and quadratic programming are implemented via the \kbd{ROI} package which acts as an interface to the \kbd{Rglpk}, \kbd{Rsymphony}, and \kbd{quadprog} packages.
+
+A key strength of \kbd{PortfolioAnalytics} is the generalization of constraints and objectives that can be solved.
+
+If \code{optimize_method="ROI"} is specified, a default solver will be selected based on the optimization problem. The \code{glpk} solver is the default solver for LP and MILP optimization problems. The \code{quadprog} solver is the default solver for QP optimization problems. For example, \code{optimize_method = "quadprog"} can be specified and the optimization problem will be solved via ROI using the quadprog plugin package.
+
+The extension to ROI solves a limited type of convex optimization problems:
\itemize{
- \item Maxmimize portfolio return subject leverage, box, group, position limit, target mean return, and/or factor exposure constraints on weights.
- \item Minimize portfolio variance subject to leverage, box, group, turnover, and/or factor exposure constraints (otherwise known as global minimum variance portfolio).
- \item Minimize portfolio variance subject to leverage, box, group, and/or factor exposure constraints and a desired portfolio return.
- \item Maximize quadratic utility subject to leverage, box, group, target mean return, turnover, and/or factor exposure constraints and risk aversion parameter.
- \item Minimize ETL subject to leverage, box, group, position limit, target mean return, and/or factor exposure constraints and target portfolio return.
+\item{Maxmimize portfolio return subject leverage, box, group, position limit, target mean return, and/or factor exposure constraints on weights.}
+\item{Minimize portfolio variance subject to leverage, box, group, turnover, and/or factor exposure constraints (otherwise known as global minimum variance portfolio).}
+\item{Minimize portfolio variance subject to leverage, box, group, and/or factor exposure constraints and a desired portfolio return.}
+\item{Maximize quadratic utility subject to leverage, box, group, target mean return, turnover, and/or factor exposure constraints and risk aversion parameter.
+(The risk aversion parameter is passed into \code{optimize.portfolio} as an added argument to the \code{portfolio} object).}
+\item{Maximize portfolio mean return per unit standard deviation (i.e. the Sharpe Ratio) can be done by specifying \code{maxSR=TRUE} in \code{optimize.portfolio}.
+If both mean and StdDev are specified as objective names, the default action is to maximize quadratic utility, therefore \code{maxSR=TRUE} must be specified to maximize Sharpe Ratio.}
+\item{Minimize portfolio ES/ETL/CVaR optimization subject to leverage, box, group, position limit, target mean return, and/or factor exposure constraints and target portfolio return.}
+\item{Maximize portfolio mean return per unit ES/ETL/CVaR (i.e. the STARR Ratio) can be done by specifying \code{maxSTARR=TRUE} in \code{optimize.portfolio}.
+If both mean and ES/ETL/CVaR are specified as objective names, the default action is to maximize mean return per unit ES/ETL/CVaR.}
}
+These problems also support a weight_concentration objective where concentration of weights as measured by HHI is added as a penalty term to the quadratic objective.
-Many real-world portfolio optimization problems are global optimization problems, and therefore are not suitable for linear or quadratic programming routines. \kbd{PortfolioAnalytics} provides a random portfolio optimization method, and also utilizes the \R packages DEoptim, pso, and GenSA for solving non-convex global optimization problems. \kbd{PortfolioAnalytics} supports three methods of generating random portfolios.
+Because these convex optimization problem are standardized, there is no need for a penalty term. The \code{multiplier} argument in \code{\link{add.objective}} passed into the complete constraint object are ingnored by the ROI solver.
+Many real-world portfolio optimization problems are global optimization problems, and therefore are not suitable for linear or quadratic programming routines. \kbd{PortfolioAnalytics} provides a random portfolio optimization method and also utilizes the \R packages DEoptim, pso, and GenSA for solving non-convex global optimization problems.
+
+\kbd{PortfolioAnalytics} supports three methods of generating random portfolios.
\itemize{
\item The sample method to generate random portfolios is based on an idea by Pat Burns. This is the most flexible method, but also the slowest, and can generate portfolios to satisfy leverage, box, group, and position limit constraints.
- \item The simplex method to generate random portfolios is based on a paper by W. T. Shaw. The simplex method is useful to generate random portfolios with the full investment constraint, where the sum of the weights is equal to 1, and min box constraints. Values for min_sum and max_sum of the leverage constraint will be ignored, the sum of weights will equal 1. All other constraints such as the box constraint max, group and position limit constraints will be handled by elimination. If the constraints are very restrictive, this may result in very few feasible portfolios remaining. Another key point to note is that the solution may not be along the vertexes depending on the objective. For example, a risk budget objective will likely place the portfolio somewhere on the interior.
+ \item The simplex method to generate random portfolios is based on a paper by W. T. Shaw. The simplex method is useful to generate random portfolios with the full investment constraint (where the sum of the weights is equal to 1) and min box constraints. Values for min_sum and max_sum of the leverage constraint will be ignored, the sum of weights will equal 1. All other constraints such as the box constraint max, group and position limit constraints will be handled by elimination. If the constraints are very restrictive, this may result in very few feasible portfolios remaining. Another key point to note is that the solution may not be along the vertexes depending on the objective. For example, a risk budget objective will likely place the portfolio somewhere on the interior.
\item The grid method to generate random portfolios is based on the \code{gridSearch} function in package \kbd{NMOF}. The grid search method only satisfies the min and max box constraints. The min_sum and max_sum leverage constraint will likely be violated and the weights in the random portfolios should be normalized. Normalization may cause the box constraints to be violated and will be penalized in \code{constrained_objective}.
}
-\kbd{PortfolioAnalytics} leverages the \kbd{PerformanceAnalytics} package for many common objective functions. The objective types in \kbd{PortfolioAnalytics} are designed to be used with \kbd{PerformanceAnalytics} functions, but any user supplied valid R function can be used as an objective.
-
-This summary attempts to provide an overview of how to construct a portfolio object with constraints and objectives, run the optimization, and chart the results.
+\kbd{PortfolioAnalytics} leverages the \kbd{PerformanceAnalytics} package for many common objective functions. The objective types in \kbd{PortfolioAnalytics} are designed to be used with \kbd{PerformanceAnalytics} functions, but any user supplied valid \R function can be used as an objective.
}
\section{Optimization}{
-The portfolio object is instantiated with the \code{\link{portfolio.spec}} function. The main argument to \code{\link{portfolio.spec}} is \code{assets}. The \code{assets} argument can be a scalar value for the number of assets, a character vector of fund names, or a named vector of initial weights.
+This summary attempts to provide an overview of how to construct a portfolio object with constraints and objectives, run the optimization, and chart the results.
-Adding constraints to the portfolio object is done with \code{\link{add.constraint}}. The \code{\link{add.constraint}} function is the main interface for adding and/or updating constraints to the portfolio object. This function allows the user to specify the portfolio to add the constraints to, the type of constraints, arguments for the constraint, and whether or not to enable the constraint. If updating an existing constraint, the indexnum argument can be specified.
+The portfolio object is initialized with the \code{\link{portfolio.spec}} function. The main argument to \code{\link{portfolio.spec}} is \code{assets}. The \code{assets} argument can be a scalar value for the number of assets, a character vector of fund names, or a named vector of initial weights.
-Objectives can be added to the portfolio object with \code{\link{add.objective}}. The \code{\link{add.objective}} function is the main function for adding and/or updating objectives to the portfolio object. This function allows the user to specify the portfolio to add the objectives to, the type, name of the objective function, arguments to the objective function, and whether or not to enable the objective. If updating an existing constraint, the indexnum argument can be specified.
+Adding constraints to the portfolio object is done with \code{\link{add.constraint}}. The \code{\link{add.constraint}} function is the main interface for adding and/or updating constraints to the portfolio object. This function allows the user to specify the portfolio to add the constraints to, the type of constraints, arguments for the constraint, and whether or not to enable the constraint. If updating an existing constraint, the \code{indexnum} argument can be specified.
+Objectives can be added to the portfolio object with \code{\link{add.objective}}. The \code{\link{add.objective}} function is the main function for adding and/or updating objectives to the portfolio object. This function allows the user to specify the portfolio to add the objectives to, the type, name of the objective function, arguments to the objective function, and whether or not to enable the objective. If updating an existing objective, the \code{indexnum} argument can be specified.
+
With the constraints and objectives specified in the portfolio object, the portfolio object can be passed to \code{\link{optimize.portfolio}} or \code{\link{optimize.portfolio.rebalancing}} to run the optimization. Arguments to \code{\link{optimize.portfolio}} include asset returns, the portfolio obect specifying constraints and objectives, optimization method, and other parameters specific to the solver. \code{\link{optimize.portfolio.rebalancing}} adds support for backtesting portfolio optimization through time with rebalancing or rolling periods.
}
@@ -53,6 +77,16 @@
Multiple objects created via \code{\link{optimize.portfolio}} can be combined with \code{\link{combine.optimizations}} for visual comparison. The weights of the optimal portfolios can be plotted with \code{\link{chart.Weights}}. The optimal portfolios can be compared in risk-reward space with \code{\link{chart.RiskReward}}. The portfolio component risk contributions of the multiple optimal portfolios can be plotted with \code{\link{chart.RiskBudget}}.
}
+\section{Package Dependencies}{
+Several of the functions in the \kbd{PortfolioAnalytics} package require time series data of returns and the \code{\link[xts]{xts}} package is used for working with time series data.
+
+The \kbd{PerformanceAnalytics} package is used for many common objective functions. The objective types in \kbd{PortfolioAnalytics} are designed to be used with \kbd{PerformanceAnalytics} functions such as \code{\link[PerformanceAnalytics]{StdDev}}, \code{\link[PerformanceAnalytics]{VaR}}, and \code{\link[PerformanceAnalytics]{ES}}.
+
+The \kbd{foreach} and \kbd{iterators} packages are used extensively throughout the package to support parallel programming. The primary functions where \code{foreach} loops are used is \code{\link{optimize.portfolio}}, \code{\link{optimize.portfolio.rebalancing}}, and \code{\link{create.EfficientFrontier}}.
+
+In addition to a random portfolios optimzation method, \kbd{PortfolioAnalytics} supports backend solvers by leveraging the following packages: \kbd{DEoptim}, \kbd{pso}, \kbd{GenSA}, \kbd{ROI} and associated ROI plugin packages.
+}
+
\section{Further Work}{
Continued work to improved charts and graphs.
From noreply at r-forge.r-project.org Tue Apr 15 02:11:32 2014
From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org)
Date: Tue, 15 Apr 2014 02:11:32 +0200 (CEST)
Subject: [Returnanalytics-commits] r3367 - in pkg/PortfolioAnalytics: R demo
Message-ID: <20140415001132.35ACD1861D9@r-forge.r-project.org>
Author: rossbennett34
Date: 2014-04-15 02:11:31 +0200 (Tue, 15 Apr 2014)
New Revision: 3367
Modified:
pkg/PortfolioAnalytics/R/extract.efficient.frontier.R
pkg/PortfolioAnalytics/demo/demo_efficient_frontier.R
Log:
updates to efficient frontier code to minimize checks and allow a constraint only portfolio object.
Modified: pkg/PortfolioAnalytics/R/extract.efficient.frontier.R
===================================================================
--- pkg/PortfolioAnalytics/R/extract.efficient.frontier.R 2014-04-14 21:09:50 UTC (rev 3366)
+++ pkg/PortfolioAnalytics/R/extract.efficient.frontier.R 2014-04-15 00:11:31 UTC (rev 3367)
@@ -13,71 +13,73 @@
extract.efficient.frontier <- function (object=NULL, match.col='ES', from=NULL, to=NULL, by=0.005, n.portfolios=NULL, ..., R=NULL, portfolio=NULL, optimize_method='random')
{
- #TODO add a threshold argument for how close it has to be to count
- # do we need to recalc the constrained_objective too? I don't think so.
- if(!inherits(object, "optimize.portfolio")) stop("object passed in must of of class 'portfolio'")
-
- #set<-seq(from=from,to=to,by=by)
- #set<-cbind(quantmod::Lag(set,1),as.matrix(set))[-1,]
- if(is.null(object)){
- if(!is.null(R) & !is.null(portfolio)){
- portfolios<-optimize.portfolio(portfolio=portfolio, R=R, optimize_method=optimize_method[1], trace=TRUE, ...)
- } else {
- stop('you must specify a portfolio object and a return series or an objective of class optimize.portfolio')
- }
- }
-
- xtract<-extractStats(object)
- columnnames=colnames(xtract)
- # optimal portfolio stats from xtract
- opt <- xtract[which.min(xtract[, "out"]),]
- #if("package:multicore" %in% search() || require("multicore",quietly = TRUE)){
- # mclapply
- #}
- stopifnot("package:foreach" %in% search() || require("foreach",quietly = TRUE))
-# rtc = pmatch(return.col,columnnames)
-# if(is.na(rtc)) {
-# rtc = pmatch(paste(return.col,return.col,sep='.'),columnnames)
-# }
- mtc = pmatch(match.col,columnnames)
- if(is.na(mtc)) {
- mtc = pmatch(paste(match.col,match.col,sep='.'),columnnames)
- }
- if(is.na(mtc)) stop("could not match match.col with column name of extractStats output")
-
- if(is.null(from)){
- from <- min(xtract[, mtc])
- }
- if(is.null(to)){
- to <- max(xtract[, mtc])
- }
- if(!is.null(n.portfolios)){
- # create the sequence using length.out if the user has specified a value for the n.portfolios arg
- set<-seq(from=from, to=to, length.out=n.portfolios)
+ #TODO add a threshold argument for how close it has to be to count
+ # do we need to recalc the constrained_objective too? I don't think so.
+ if(!inherits(object, "optimize.portfolio")) stop("object passed in must of of class 'portfolio'")
+
+ #set<-seq(from=from,to=to,by=by)
+ #set<-cbind(quantmod::Lag(set,1),as.matrix(set))[-1,]
+ if(is.null(object)){
+ if(!is.null(R) & !is.null(portfolio)){
+ portfolios<-optimize.portfolio(portfolio=portfolio, R=R, optimize_method=optimize_method[1], trace=TRUE, ...)
} else {
- # fall back to using by to create the sequence
- set<-seq(from=from, to=to, by=by)
+ stop('you must specify a portfolio object and a return series or an objective of class optimize.portfolio')
}
-
- set<-cbind(quantmod::Lag(set,1),as.matrix(set))[-1,]
- result <- foreach(i=1:nrow(set),.inorder=TRUE, .combine=rbind, .errorhandling='remove') %do% {
- tmp<-xtract[which(xtract[,mtc]>=set[i,1] & xtract[,mtc]=set[i,1] & xtract[,mtc]= 1){
+ # the portfolio object has a var, StdDev, or sd objective
+ var_obj <- portfolio$objectives[[var_idx]]
+ } else {
+ var_obj <- portfolio_risk_objective(name="var")
}
- # for a mean-var efficient frontier, there must be two objectives 1) "mean" and 2) "var"
- if(!((length(objnames) >= 2) & ("var" %in% objnames | "StdDev" %in% objnames | "sd" %in% objnames) & ("mean" %in% objnames))){
- stop("The portfolio object must have both 'mean' and 'var', 'StdDev', or'sd' specified as objectives")
- }
+ # Clear out the objectives in portfolio and add them here to simplify checks
+ # and so we can control the optimization along the efficient frontier.
+ portfolio$objectives <- list()
+ portfolio$objectives[[1]] <- var_obj
+ portfolio <- add.objective(portfolio=portfolio, type="return", name="mean")
# If the user has passed in a portfolio object with return_constraint, we need to disable it
for(i in 1:length(portfolio$constraints)){
@@ -128,9 +126,6 @@
##### get the maximum return #####
- # set the risk_aversion to a very small number for equivalent to max return portfolio
- # portfolio$objectives[[var_idx]]$risk_aversion <- 1e-6
-
# Disable the risk objective
portfolio$objectives[[var_idx]]$enabled <- FALSE
@@ -141,9 +136,6 @@
##### Get the return at the minimum variance portfolio #####
- # set the risk_aversion to a very large number equivalent to a minvar portfolio
- # portfolio$objectives[[var_idx]]$risk_aversion <- 1e6
-
# Disable the return objective
portfolio$objectives[[mean_idx]]$enabled <- FALSE
@@ -165,11 +157,12 @@
ret_constr_idx <- which(unlist(lapply(portfolio$constraints, function(x) inherits(x, "return_constraint"))))
stopifnot("package:foreach" %in% search() || require("foreach",quietly = TRUE))
+ stopifnot("package:iterators" %in% search() || require("iterators",quietly = TRUE))
if(!is.null(risk_aversion)){
# Enable the return objective so we are doing quadratic utility
portfolio$objectives[[mean_idx]]$enabled <- TRUE
- out <- foreach(i=1:length(risk_aversion), .inorder=TRUE, .combine=rbind, .errorhandling='remove') %dopar% {
- portfolio$objectives[[var_idx]]$risk_aversion <- risk_aversion[i]
+ out <- foreach(lambda=iter(risk_aversion), .inorder=TRUE, .combine=rbind, .errorhandling='remove', .packages='PortfolioAnalytics') %dopar% {
+ portfolio$objectives[[var_idx]]$risk_aversion <- lambda
extractStats(optimize.portfolio(R=R, portfolio=portfolio, optimize_method="ROI", ...=...))
}
out <- cbind(out, risk_aversion)
@@ -177,8 +170,8 @@
} else {
# Enable the return constraint
portfolio$constraints[[ret_constr_idx]]$enabled <- TRUE
- out <- foreach(i=1:length(ret_seq), .inorder=TRUE, .combine=rbind, .errorhandling='remove') %dopar% {
- portfolio$constraints[[ret_constr_idx]]$return_target <- ret_seq[i]
+ out <- foreach(ret=iter(ret_seq), .inorder=TRUE, .combine=rbind, .errorhandling='remove', .packages='PortfolioAnalytics') %dopar% {
+ portfolio$constraints[[ret_constr_idx]]$return_target <- ret
opt <- optimize.portfolio(R=R, portfolio=portfolio, optimize_method="ROI", ...=...)
c(sum(extractWeights(opt) * mean_ret), extractStats(opt))
}
@@ -191,10 +184,10 @@
#' Generate the efficient frontier for a mean-etl portfolio
#'
#' This function generates the mean-ETL efficient frontier of a portfolio
-#' specifying constraints and objectives. To generate the mean-ETL efficient
-#' frontier, the portfolio must have two objectives 1) "mean" and 2) "ETL/ES/CVaR". If
-#' the only objective in the \code{portfolio} object is ETL/ES/CVaR, the we will
-#' add a mean objective.
+#' specifying the constraints and objectives. The \code{portfolio} object
+#' should have two objectives: 1) mean and 2) ES (or ETL or cVaR). If the
+#' portfolio object does not contain these objectives, they will be added
+#' using default parameters.
#'
#' @param portfolio a portfolio object with constraints and objectives created via \code{\link{portfolio.spec}}
#' @param R an xts or matrix of asset returns
@@ -210,26 +203,25 @@
# step 3: 'step' along the returns and run the optimization to calculate
# the weights and objective measures along the efficient frontier
- objnames <- unlist(lapply(portfolio$objectives, function(x) x$name))
-
- if(length(objnames) == 1){
- if(objnames == "mean"){
- # The user has only passed in a mean objective, add ES objective to the portfolio
- portfolio <- add.objective(portfolio=portfolio, type="risk", name="ES")
- } else if(objnames %in% c("ETL", "ES", "CVaR")){
- # The user has only passed in ETL/ES/CVaR objective, add a mean objective
- portfolio <- add.objective(portfolio=portfolio, type="return", name="mean")
- }
- # get the objective names again after we add an objective to the portfolio
- objnames <- unlist(lapply(portfolio$objectives, function(x) x$name))
+ # Use the portfolio_risk_objective from the portfolio if they have it
+ # check for a ETL, ES, or cVaR objective
+ etl_idx <- which(unlist(lapply(portfolio$objectives, function(x) x$name)) %in% c("ETL", "ES", "CVaR"))
+ if(length(etl_idx) >= 1){
+ # the portfolio object has a ETL, ES, CVaR objective
+ etl_obj <- portfolio$objectives[[etl_idx]]
+ } else {
+ etl_obj <- portfolio_risk_objective(name="ES", arguments=list(p=0.95))
}
- # for a mean-etl efficient frontier, there must be two objectives 1) "mean" and 2) "ETL/ES/CVaR"
- # get the names of the objectives
- if(!((length(objnames) == 2) & any(objnames %in% c("ETL", "ES", "CVaR")) & ("mean" %in% objnames))){
- stop("The portfolio object must have both 'mean' and 'var' specified as objectives")
- }
+ # Clear out the objectives in portfolio and add them here to simplify checks
+ # and so we can control the optimization along the efficient frontier.
+ portfolio$objectives <- list()
+ portfolio$objectives[[1]] <- etl_obj
+ portfolio <- add.objective(portfolio=portfolio, type="return", name="mean")
+ # get the objective names from the portfolio object
+ objnames <- unlist(lapply(portfolio$objectives, function(x) x$name))
+
# If the user has passed in a portfolio object with return_constraint, we need to disable it
for(i in 1:length(portfolio$constraints)){
if(inherits(portfolio$constraints[[i]], "return_constraint")){
@@ -258,14 +250,15 @@
# length.out is the number of portfolios to create
ret_seq <- seq(from=minret, to=maxret, length.out=n.portfolios)
-# out <- matrix(0, nrow=length(ret_seq), ncol=length(extractStats(tmp)))
-# for(i in 1:length(ret_seq)){
-# portfolio$objectives[[mean_idx]]$target <- ret_seq[i]
-# out[i, ] <- extractStats(optimize.portfolio(R=R, portfolio=portfolio, optimize_method="ROI"))
-# }
+ # out <- matrix(0, nrow=length(ret_seq), ncol=length(extractStats(tmp)))
+ # for(i in 1:length(ret_seq)){
+ # portfolio$objectives[[mean_idx]]$target <- ret_seq[i]
+ # out[i, ] <- extractStats(optimize.portfolio(R=R, portfolio=portfolio, optimize_method="ROI"))
+ # }
stopifnot("package:foreach" %in% search() || require("foreach",quietly = TRUE))
- out <- foreach(i=1:length(ret_seq), .inorder=TRUE, .combine=rbind, .errorhandling='remove') %dopar% {
- portfolio$objectives[[mean_idx]]$target <- ret_seq[i]
+ stopifnot("package:iterators" %in% search() || require("iterators",quietly = TRUE))
+ out <- foreach(ret=iter(ret_seq), .inorder=TRUE, .combine=rbind, .errorhandling='remove', .packages='PortfolioAnalytics') %dopar% {
+ portfolio$objectives[[mean_idx]]$target <- ret
extractStats(optimize.portfolio(R=R, portfolio=portfolio, optimize_method="ROI", ef=TRUE, ...=...))
}
colnames(out) <- names(stats)
@@ -280,12 +273,16 @@
#' \item{"mean-var", "mean-sd", or "mean-StdDev":}{ This is a special case for
#' an efficient frontier that can be created by a QP solver.
#' The \code{portfolio} object should have two
-#' objectives: 1) mean and 2) var. The efficient frontier will be created via
+#' objectives: 1) mean and 2) var. If the portfolio object does not contain these
+#' objectives, they will be added using default parameters.
+#' The efficient frontier will be created via
#' \code{\link{meanvar.efficient.frontier}}.}
#' \item{"mean-ETL", "mean-ES", "mean-CVaR", "mean-etl":}{ This is a special
#' case for an efficient frontier that can be created by an LP solver.
#' The \code{portfolio} object should have two objectives: 1) mean
-#' and 2) ETL/ES/CVaR. The efficient frontier will be created via
+#' and 2) ETL/ES/CVaR. If the portfolio object does not contain these
+#' objectives, they will be added using default parameters.
+#' The efficient frontier is created via
#' \code{\link{meanetl.efficient.frontier}}.}
#' \item{"DEoptim":}{ This can handle more complex constraints and objectives
#' than the simple mean-var and mean-ETL cases. For this type, we actually
Modified: pkg/PortfolioAnalytics/demo/demo_efficient_frontier.R
===================================================================
--- pkg/PortfolioAnalytics/demo/demo_efficient_frontier.R 2014-04-14 21:09:50 UTC (rev 3366)
+++ pkg/PortfolioAnalytics/demo/demo_efficient_frontier.R 2014-04-15 00:11:31 UTC (rev 3367)
@@ -27,19 +27,18 @@
group_min=0.05,
group_max=0.7)
-# initial objective
-init <- add.objective(portfolio=init, type="return", name="mean")
-
# create mean-etl portfolio
meanetl.portf <- add.objective(portfolio=init, type="risk", name="ES")
+meanetl.portf <- add.objective(portfolio=meanetl.portf, type="return", name="mean")
# create mean-var portfolio
-meanvar.portf <- add.objective(portfolio=init, type="risk", name="var", risk_aversion=1e6)
+meanvar.portf <- add.objective(portfolio=init, type="risk", name="var", risk_aversion=10)
+meanvar.portf <- add.objective(portfolio=meanvar.portf, type="return", name="mean")
# create efficient frontiers
# mean-var efficient frontier
-meanvar.ef <- create.EfficientFrontier(R=R, portfolio=meanvar.portf, type="mean-StdDev")
+meanvar.ef <- create.EfficientFrontier(R=R, portfolio=init, type="mean-StdDev")
meanvar.ef
summary(meanvar.ef, digits=2)
meanvar.ef$frontier
@@ -113,7 +112,7 @@
chart.Weights.EF(ef, match.col="StdDev", colorset=bluemono, by.groups=TRUE)
# mean-etl efficient frontier
-meanetl.ef <- create.EfficientFrontier(R=R, portfolio=meanetl.portf, type="mean-ES")
+meanetl.ef <- create.EfficientFrontier(R=R, portfolio=init, type="mean-ES")
meanetl.ef
summary(meanetl.ef)
meanetl.ef$frontier
@@ -136,8 +135,6 @@
# set up an initial portfolio with the full investment constraint and mean and var objectives
init.portf <- portfolio.spec(assets=funds)
init.portf <- add.constraint(portfolio=init.portf, type="full_investment")
-init.portf <- add.objective(portfolio=init.portf, type="risk", name="var")
-init.portf <- add.objective(portfolio=init.portf, type="return", name="mean")
# long only constraints
lo.portf <- add.constraint(portfolio=init.portf, type="long_only")
@@ -154,10 +151,28 @@
group.portf <- add.constraint(portfolio=group.portf, type="long_only")
# optimize.portfolio(R=R, portfolio=group.portf, optimize_method="ROI")
-portf.list <- list(lo.portf, box.portf, group.portf)
+portf.list <- combine.portfolios(list(lo.portf, box.portf, group.portf))
legend.labels <- c("Long Only", "Box", "Group + Long Only")
chart.EfficientFrontierOverlay(R=R, portfolio_list=portf.list, type="mean-StdDev",
match.col="StdDev", legend.loc="topleft",
legend.labels=legend.labels, cex.legend=0.6,
labels.assets=FALSE, pch.assets=18)
+# Efficient frontier in mean-ES space with varying confidence leves for
+# ES calculation
+ES90 <- add.objective(portfolio=lo.portf, type="risk", name="ES",
+ arguments=list(p=0.9))
+
+ES92 <- add.objective(portfolio=lo.portf, type="risk", name="ES",
+ arguments=list(p=0.92))
+
+ES95 <- add.objective(portfolio=lo.portf, type="risk", name="ES",
+ arguments=list(p=0.95))
+
+portf.list <- combine.portfolios(list(ES.90=ES90, ES.92=ES92, ES.95=ES95))
+legend.labels <- c("ES (p=0.9)", "ES (p=0.92)", "ES (p=0.95)")
+chart.EfficientFrontierOverlay(R=R, portfolio_list=portf.list, type="mean-ES",
+ match.col="ES", legend.loc="topleft",
+ legend.labels=legend.labels, cex.legend=0.6,
+ labels.assets=FALSE, pch.assets=18)
+
From noreply at r-forge.r-project.org Tue Apr 15 03:49:35 2014
From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org)
Date: Tue, 15 Apr 2014 03:49:35 +0200 (CEST)
Subject: [Returnanalytics-commits] r3368 - pkg/PortfolioAnalytics/man
Message-ID: <20140415014936.4E196186B73@r-forge.r-project.org>
Author: rossbennett34
Date: 2014-04-15 03:49:25 +0200 (Tue, 15 Apr 2014)
New Revision: 3368
Modified:
pkg/PortfolioAnalytics/man/create.EfficientFrontier.Rd
pkg/PortfolioAnalytics/man/meanetl.efficient.frontier.Rd
pkg/PortfolioAnalytics/man/meanvar.efficient.frontier.Rd
Log:
Updating man files for efficient frontier
Modified: pkg/PortfolioAnalytics/man/create.EfficientFrontier.Rd
===================================================================
--- pkg/PortfolioAnalytics/man/create.EfficientFrontier.Rd 2014-04-15 00:11:31 UTC (rev 3367)
+++ pkg/PortfolioAnalytics/man/create.EfficientFrontier.Rd 2014-04-15 01:49:25 UTC (rev 3368)
@@ -49,13 +49,17 @@
"mean-sd", or "mean-StdDev":}{ This is a special case for
an efficient frontier that can be created by a QP solver.
The \code{portfolio} object should have two objectives:
- 1) mean and 2) var. The efficient frontier will be
+ 1) mean and 2) var. If the portfolio object does not
+ contain these objectives, they will be added using
+ default parameters. The efficient frontier will be
created via \code{\link{meanvar.efficient.frontier}}.}
\item{"mean-ETL", "mean-ES", "mean-CVaR", "mean-etl":}{
This is a special case for an efficient frontier that can
be created by an LP solver. The \code{portfolio} object
should have two objectives: 1) mean and 2) ETL/ES/CVaR.
- The efficient frontier will be created via
+ If the portfolio object does not contain these
+ objectives, they will be added using default parameters.
+ The efficient frontier is created via
\code{\link{meanetl.efficient.frontier}}.}
\item{"DEoptim":}{ This can handle more complex
constraints and objectives than the simple mean-var and
Modified: pkg/PortfolioAnalytics/man/meanetl.efficient.frontier.Rd
===================================================================
--- pkg/PortfolioAnalytics/man/meanetl.efficient.frontier.Rd 2014-04-15 00:11:31 UTC (rev 3367)
+++ pkg/PortfolioAnalytics/man/meanetl.efficient.frontier.Rd 2014-04-15 01:49:25 UTC (rev 3368)
@@ -23,11 +23,11 @@
}
\description{
This function generates the mean-ETL efficient frontier
- of a portfolio specifying constraints and objectives. To
- generate the mean-ETL efficient frontier, the portfolio
- must have two objectives 1) "mean" and 2) "ETL/ES/CVaR".
- If the only objective in the \code{portfolio} object is
- ETL/ES/CVaR, the we will add a mean objective.
+ of a portfolio specifying the constraints and objectives.
+ The \code{portfolio} object should have two objectives:
+ 1) mean and 2) ES (or ETL or cVaR). If the portfolio
+ object does not contain these objectives, they will be
+ added using default parameters.
}
\author{
Ross Bennett
Modified: pkg/PortfolioAnalytics/man/meanvar.efficient.frontier.Rd
===================================================================
--- pkg/PortfolioAnalytics/man/meanvar.efficient.frontier.Rd 2014-04-15 00:11:31 UTC (rev 3367)
+++ pkg/PortfolioAnalytics/man/meanvar.efficient.frontier.Rd 2014-04-15 01:49:25 UTC (rev 3368)
@@ -6,8 +6,8 @@
n.portfolios = 25, risk_aversion = NULL, ...)
}
\arguments{
- \item{portfolio}{a portfolio object with constraints and
- objectives created via \code{\link{portfolio.spec}}}
+ \item{portfolio}{a portfolio object with constraints
+ created via \code{\link{portfolio.spec}}}
\item{R}{an xts or matrix of asset returns}
@@ -29,10 +29,11 @@
}
\description{
This function generates the mean-variance efficient
- frontier of a portfolio specifying constraints and
- objectives. To generate the mean-var efficient frontier,
- the portfolio must have two objectives 1) "mean" and 2)
- "var".
+ frontier of a portfolio specifying the constraints and
+ objectives. The \code{portfolio} object should have two
+ objectives: 1) mean and 2) var (or sd or StdDev). If the
+ portfolio object does not contain these objectives, they
+ will be added using default parameters.
}
\author{
Ross Bennett
From noreply at r-forge.r-project.org Tue Apr 15 18:49:32 2014
From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org)
Date: Tue, 15 Apr 2014 18:49:32 +0200 (CEST)
Subject: [Returnanalytics-commits] r3369 - in pkg/PortfolioAnalytics: R man
Message-ID: <20140415164933.032A518670D@r-forge.r-project.org>
Author: rossbennett34
Date: 2014-04-15 18:49:32 +0200 (Tue, 15 Apr 2014)
New Revision: 3369
Modified:
pkg/PortfolioAnalytics/R/constraints.R
pkg/PortfolioAnalytics/R/objective.R
pkg/PortfolioAnalytics/man/add.constraint.Rd
pkg/PortfolioAnalytics/man/add.objective.Rd
pkg/PortfolioAnalytics/man/print.summary.optimize.portfolio.rebalancing.Rd
Log:
adding examples to add.constraint and add.objective
Modified: pkg/PortfolioAnalytics/R/constraints.R
===================================================================
--- pkg/PortfolioAnalytics/R/constraints.R 2014-04-15 01:49:25 UTC (rev 3368)
+++ pkg/PortfolioAnalytics/R/constraints.R 2014-04-15 16:49:32 UTC (rev 3369)
@@ -255,6 +255,29 @@
#'
#' # Add target mean return constraint
#' pspec <- add.constraint(portfolio=pspec, type="return", return_target=0.007)
+#'
+#' # Example using the indexnum argument
+#' portf <- portfolio.spec(assets=fund.names)
+#' portf <- add.constraint(portf, type="full_investment")
+#' portf <- add.constraint(portf, type="long_only")
+#'
+#' # indexnum corresponds to the index number of the constraint
+#' # The full_investment constraint was the first constraint added and has
+#' # indexnum=1
+#' portf$constraints[[1]]
+#'
+#' # View the constraint with indexnum=2
+#' portf$constraints[[2]]
+#'
+#' # Update the constraint to relax the sum of weights constraint
+#' portf <- add.constraint(portf, type="weight_sum",
+#' min_sum=0.99, max_sum=1.01,
+#' indexnum=1)
+#'
+#' # Update the constraint to modify the box constraint
+#' portf <- add.constraint(portf, type="box",
+#' min=0.1, max=0.8,
+#' indexnum=2)
#' @export
add.constraint <- function(portfolio, type, enabled=TRUE, message=FALSE, ..., indexnum=NULL){
# Check to make sure that the portfolio passed in is a portfolio object
Modified: pkg/PortfolioAnalytics/R/objective.R
===================================================================
--- pkg/PortfolioAnalytics/R/objective.R 2014-04-15 01:49:25 UTC (rev 3368)
+++ pkg/PortfolioAnalytics/R/objective.R 2014-04-15 16:49:32 UTC (rev 3369)
@@ -223,12 +223,60 @@
#' @param arguments default arguments to be passed to an objective function when executed
#' @param enabled TRUE/FALSE
#' @param \dots any other passthru parameters
-#' @param indexnum if you are updating a specific constraint, the index number in the $objectives list to update
+#' @param indexnum if you are updating a specific objective, the index number in the $objectives list to update
#' @author Brian G. Peterson and Ross Bennett
#' @aliases add.objective_v2 add.objective_v1
#' @seealso \code{\link{objective}}, \code{\link{portfolio.spec}}
#' @rdname add.objective
#' @name add.objective
+#' @examples
+#' data(edhec)
+#' returns <- edhec[,1:4]
+#' fund.names <- colnames(returns)
+#' portf <- portfolio.spec(assets=fund.names)
+#' # Add some basic constraints
+#' portf <- add.constraint(portf, type="full_investment")
+#' portf <- add.constraint(portf, type="long_only")
+#'
+#' # Creates a new portfolio object using portf and adds a quadratic utility
+#' # objective. This will add two objectives to the portfolio object; 1) mean and
+#' # 2) var. The risk aversion parameter is commonly referred to as lambda in the
+#' # quadratic utility formulation that controls how much the portfolio variance
+#' # is penalized.
+#' portf.maxQU <- add.objective(portf, type="quadratic_utility",
+#' risk_aversion=0.25)
+#'
+#' # Creates a new portfolio object using portf and adds mean as an objective
+#' portf.maxMean <- add.objective(portf, type="return", name="mean")
+#'
+#' # Creates a new portfolio object using portf and adds StdDev as an objective
+#' portf.minStdDev <- add.objective(portf, type="risk", name="StdDev")
+#'
+#' # Creates a new portfolio object using portf and adds ES as an objective.
+#' # Note that arguments to ES are passed in as a named list.
+#' portf.minES <- add.objective(portf, type="risk", name="ES",
+#' arguments=list(p=0.925, clean="boudt"))
+#'
+#' # Creates a new portfolio object using portf.minES and adds a risk budget
+#' # objective with limits on component risk contribution.
+#' # Note that arguments to ES are passed in as a named list.
+#' portf.RiskBudgetES <- add.objective(portf.minES, type="risk_budget", name="ES",
+#' arguments=list(p=0.925, clean="boudt"),
+#' min_prisk=0, max_prisk=0.6)
+#'
+#' # Creates a new portfolio object using portf.minES and adds a risk budget
+#' # objective with equal component risk contribution.
+#' # Note that arguments to ES are passed in as a named list.
+#' portf.EqRiskES <- add.objective(portf.minES, type="risk_budget", name="ES",
+#' arguments=list(p=0.925, clean="boudt"),
+#' min_concentration=TRUE)
+#'
+#' # Creates a new portfolio object using portf and adds a weight_concentration
+#' # objective. The conc_aversion parameter controls how much concentration is
+#' # penalized. The portfolio concentration is defined as the Herfindahl Hirschman
+#' # Index of the weights.
+#' portf.conc <- add.objective(portf, type="weight_concentration",
+#' name="HHI", conc_aversion=0.01)
#' @export
add.objective <- add.objective_v2
Modified: pkg/PortfolioAnalytics/man/add.constraint.Rd
===================================================================
--- pkg/PortfolioAnalytics/man/add.constraint.Rd 2014-04-15 01:49:25 UTC (rev 3368)
+++ pkg/PortfolioAnalytics/man/add.constraint.Rd 2014-04-15 16:49:32 UTC (rev 3369)
@@ -102,6 +102,29 @@
# Add target mean return constraint
pspec <- add.constraint(portfolio=pspec, type="return", return_target=0.007)
+
+# Example using the indexnum argument
+portf <- portfolio.spec(assets=fund.names)
+portf <- add.constraint(portf, type="full_investment")
+portf <- add.constraint(portf, type="long_only")
+
+# indexnum corresponds to the index number of the constraint
+# The full_investment constraint was the first constraint added and has
+# indexnum=1
+portf$constraints[[1]]
+
+# View the constraint with indexnum=2
+portf$constraints[[2]]
+
+# Update the constraint to relax the sum of weights constraint
+portf <- add.constraint(portf, type="weight_sum",
+min_sum=0.99, max_sum=1.01,
+indexnum=1)
+
+# Update the constraint to modify the box constraint
+portf <- add.constraint(portf, type="box",
+min=0.1, max=0.8,
+indexnum=2)
}
\author{
Ross Bennett
Modified: pkg/PortfolioAnalytics/man/add.objective.Rd
===================================================================
--- pkg/PortfolioAnalytics/man/add.objective.Rd 2014-04-15 01:49:25 UTC (rev 3368)
+++ pkg/PortfolioAnalytics/man/add.objective.Rd 2014-04-15 16:49:32 UTC (rev 3369)
@@ -36,9 +36,8 @@
\item{\dots}{any other passthru parameters}
- \item{indexnum}{if you are updating a specific
- constraint, the index number in the $objectives list to
- update}
+ \item{indexnum}{if you are updating a specific objective,
+ the index number in the $objectives list to update}
}
\description{
This function is the main function for adding and
@@ -56,6 +55,55 @@
Objectives of type 'turnover' and 'minmax' are also
supported.
}
+\examples{
+data(edhec)
+returns <- edhec[,1:4]
+fund.names <- colnames(returns)
+portf <- portfolio.spec(assets=fund.names)
+# Add some basic constraints
+portf <- add.constraint(portf, type="full_investment")
+portf <- add.constraint(portf, type="long_only")
+
+# Creates a new portfolio object using portf and adds a quadratic utility
+# objective. This will add two objectives to the portfolio object; 1) mean and
+# 2) var. The risk aversion parameter is commonly referred to as lambda in the
+# quadratic utility formulation that controls how much the portfolio variance
+# is penalized.
+portf.maxQU <- add.objective(portf, type="quadratic_utility",
+ risk_aversion=0.25)
+
+# Creates a new portfolio object using portf and adds mean as an objective
+portf.maxMean <- add.objective(portf, type="return", name="mean")
+
+# Creates a new portfolio object using portf and adds StdDev as an objective
+portf.minStdDev <- add.objective(portf, type="risk", name="StdDev")
+
+# Creates a new portfolio object using portf and adds ES as an objective.
+# Note that arguments to ES are passed in as a named list.
+portf.minES <- add.objective(portf, type="risk", name="ES",
+ arguments=list(p=0.925, clean="boudt"))
+
+# Creates a new portfolio object using portf.minES and adds a risk budget
+# objective with limits on component risk contribution.
+# Note that arguments to ES are passed in as a named list.
+portf.RiskBudgetES <- add.objective(portf.minES, type="risk_budget", name="ES",
+ arguments=list(p=0.925, clean="boudt"),
+ min_prisk=0, max_prisk=0.6)
+
+# Creates a new portfolio object using portf.minES and adds a risk budget
+# objective with equal component risk contribution.
+# Note that arguments to ES are passed in as a named list.
+portf.EqRiskES <- add.objective(portf.minES, type="risk_budget", name="ES",
+ arguments=list(p=0.925, clean="boudt"),
+ min_concentration=TRUE)
+
+# Creates a new portfolio object using portf and adds a weight_concentration
+# objective. The conc_aversion parameter controls how much concentration is
+# penalized. The portfolio concentration is defined as the Herfindahl Hirschman
+# Index of the weights.
+portf.conc <- add.objective(portf, type="weight_concentration",
+ name="HHI", conc_aversion=0.01)
+}
\author{
Brian G. Peterson and Ross Bennett
}
Modified: pkg/PortfolioAnalytics/man/print.summary.optimize.portfolio.rebalancing.Rd
===================================================================
--- pkg/PortfolioAnalytics/man/print.summary.optimize.portfolio.rebalancing.Rd 2014-04-15 01:49:25 UTC (rev 3368)
+++ pkg/PortfolioAnalytics/man/print.summary.optimize.portfolio.rebalancing.Rd 2014-04-15 16:49:32 UTC (rev 3369)
@@ -2,8 +2,7 @@
\alias{print.summary.optimize.portfolio.rebalancing}
\title{Printing summary output of optimize.portfolio.rebalancing}
\usage{
- \method{print}{summary.optimize.portfolio.rebalancing}
- (x, ..., digits = 4)
+ \method{print}{summary.optimize.portfolio.rebalancing}(x, ..., digits = 4)
}
\arguments{
\item{x}{an object of class
From noreply at r-forge.r-project.org Tue Apr 15 19:30:19 2014
From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org)
Date: Tue, 15 Apr 2014 19:30:19 +0200 (CEST)
Subject: [Returnanalytics-commits] r3370 - pkg/FactorAnalytics/R
Message-ID: <20140415173019.A7568186EB2@r-forge.r-project.org>
Author: chenyian
Date: 2014-04-15 19:30:19 +0200 (Tue, 15 Apr 2014)
New Revision: 3370
Modified:
pkg/FactorAnalytics/R/plot.TimeSeriesFactorModel.r
Log:
fix bug in plot.TimeSeriesFactorModel.r
Modified: pkg/FactorAnalytics/R/plot.TimeSeriesFactorModel.r
===================================================================
--- pkg/FactorAnalytics/R/plot.TimeSeriesFactorModel.r 2014-04-15 16:49:32 UTC (rev 3369)
+++ pkg/FactorAnalytics/R/plot.TimeSeriesFactorModel.r 2014-04-15 17:30:19 UTC (rev 3370)
@@ -377,7 +377,7 @@
}
# function to extract contribution to sd from list
getCSD = function(x) {
- x$cr.fm
+ x$cSd.fm
}
# extract contributions to SD from list
cr.sd = sapply(factor.sd.decomp.list, getCSD)
@@ -397,7 +397,8 @@
beta = as.matrix(x$beta[i,])
fitted = alpha+as.matrix(plot.data[,factor.names])%*%beta
residual = plot.data[,i]-fitted
- tmpData = cbind(plot.data[idx,i], plot.data[idx,factor.names],
+ tmpData = cbind(coredata(plot.data[idx,i]),
+ coredata(plot.data[idx,factor.names]),
(residual[idx,]/sqrt(x$resid.variance[i])) )
colnames(tmpData)[c(1,length(tmpData))] = c(i, "residual")
factor.es.decomp.list[[i]] =
@@ -411,19 +412,21 @@
for (i in asset.names) {
# check for missing values in fund data
idx = which(!is.na(plot.data[,i]))
- tmpData = cbind(plot.data[idx,i], plot.data[idx,factor.names],
+ tmpData = cbind(coredata(plot.data[idx,i]),
+ coredata(plot.data[idx,factor.names]),
residuals(x$asset.fit[[i]])/sqrt(x$resid.variance[i]))
- colnames(tmpData)[c(1,length(tmpData))] = c(i, "residual")
+ colnames(tmpData)[c(1,dim(tmpData)[2])] = c(i, "residual")
factor.es.decomp.list[[i]] =
factorModelEsDecomposition(tmpData,
x$beta[i,],
- x$resid.variance[i], tail.prob=0.05)
+ x$resid.variance[i], tail.prob=0.05,
+ VaR.method=VaR.method)
}
}
# stacked bar charts of percent contributions to SD
getCETL = function(x) {
- x$cES
+ x$cES.fm
}
# report as positive number
cr.etl = sapply(factor.es.decomp.list, getCETL)
@@ -443,7 +446,8 @@
beta = as.matrix(x$beta[i,])
fitted = alpha+as.matrix(plot.data[,factor.names])%*%beta
residual = plot.data[,i]-fitted
- tmpData = cbind(plot.data[idx,i], plot.data[idx,factor.names],
+ tmpData = cbind(coredata(plot.data[idx,i]),
+ coredata(plot.data[idx,factor.names]),
(residual[idx,]/sqrt(x$resid.variance[i])) )
colnames(tmpData)[c(1,length(tmpData))] = c(i, "residual")
factor.VaR.decomp.list[[i]] =
@@ -456,9 +460,10 @@
for (i in asset.names) {
# check for missing values in fund data
idx = which(!is.na(plot.data[,i]))
- tmpData = cbind(plot.data[idx,i], plot.data[idx,factor.names],
+ tmpData = cbind(coredata(plot.data[idx,i]),
+ coredata(plot.data[idx,factor.names]),
residuals(x$asset.fit[[i]])/sqrt(x$resid.variance[i]))
- colnames(tmpData)[c(1,length(tmpData))] = c(i, "residual")
+ colnames(tmpData)[c(1,dim(tmpData)[2])] = c(i, "residual")
factor.VaR.decomp.list[[i]] =
factorModelVaRDecomposition(tmpData,
x$beta[i,],
From noreply at r-forge.r-project.org Tue Apr 15 19:49:26 2014
From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org)
Date: Tue, 15 Apr 2014 19:49:26 +0200 (CEST)
Subject: [Returnanalytics-commits] r3371 - pkg/FactorAnalytics/R
Message-ID: <20140415174926.989C018682D@r-forge.r-project.org>
Author: chenyian
Date: 2014-04-15 19:49:26 +0200 (Tue, 15 Apr 2014)
New Revision: 3371
Modified:
pkg/FactorAnalytics/R/fitTimeSeriesFactorModel.R
Log:
fix a bug in add.up.market.beta in fitTimeSeriesFactorModel.R
Modified: pkg/FactorAnalytics/R/fitTimeSeriesFactorModel.R
===================================================================
--- pkg/FactorAnalytics/R/fitTimeSeriesFactorModel.R 2014-04-15 17:30:19 UTC (rev 3370)
+++ pkg/FactorAnalytics/R/fitTimeSeriesFactorModel.R 2014-04-15 17:49:26 UTC (rev 3371)
@@ -146,9 +146,9 @@
for (i in assets.names) {
reg.df = na.omit(reg.xts[, c(i, factors.names)])
if(add.up.market.returns == TRUE) {
- up.beta <- apply(reg.xts[,excess.market.returns.name],1,max,0)
- reg.df = merge(reg.df,up.beta)
- }
+ reg.df$up.beta = reg.df[,excess.market.returns.name]
+ reg.df$up.beta[reg.df$up.beta <0] <- rep(0,sum(reg.df$up.beta<0))
+ }
if(add.quadratic.term == TRUE) {
quadratic.term <- reg.xts[,excess.market.returns.name]^2
reg.df = merge(reg.df,quadratic.term)
From noreply at r-forge.r-project.org Tue Apr 15 21:06:05 2014
From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org)
Date: Tue, 15 Apr 2014 21:06:05 +0200 (CEST)
Subject: [Returnanalytics-commits] r3372 - pkg/FactorAnalytics/R
Message-ID: <20140415190605.925FE187341@r-forge.r-project.org>
Author: chenyian
Date: 2014-04-15 21:06:04 +0200 (Tue, 15 Apr 2014)
New Revision: 3372
Modified:
pkg/FactorAnalytics/R/plot.StatFactorModel.r
Log:
fix bug in plot.StatFactorModel.r
Modified: pkg/FactorAnalytics/R/plot.StatFactorModel.r
===================================================================
--- pkg/FactorAnalytics/R/plot.StatFactorModel.r 2014-04-15 17:49:26 UTC (rev 3371)
+++ pkg/FactorAnalytics/R/plot.StatFactorModel.r 2014-04-15 19:06:04 UTC (rev 3372)
@@ -400,7 +400,7 @@
}
# function to extract component contribution to sd from list
getCSD = function(x) {
- x$cr.fm
+ x$cSd.fm
}
# extract contributions to SD from list
cr.sd = sapply(factor.sd.decomp.list, getCSD)
From noreply at r-forge.r-project.org Fri Apr 18 17:05:31 2014
From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org)
Date: Fri, 18 Apr 2014 17:05:31 +0200 (CEST)
Subject: [Returnanalytics-commits] r3373 - in pkg/PortfolioAnalytics: .
vignettes
Message-ID: <20140418150531.9C6B5187362@r-forge.r-project.org>
Author: rossbennett34
Date: 2014-04-18 17:05:31 +0200 (Fri, 18 Apr 2014)
New Revision: 3373
Modified:
pkg/PortfolioAnalytics/DESCRIPTION
pkg/PortfolioAnalytics/vignettes/risk_budget_optimization.Rnw
Log:
Update to DESCRIPTION file for PerformanceAnalytics version and risk budget vignette to use quarterly rebalancing.
Modified: pkg/PortfolioAnalytics/DESCRIPTION
===================================================================
--- pkg/PortfolioAnalytics/DESCRIPTION 2014-04-15 19:06:04 UTC (rev 3372)
+++ pkg/PortfolioAnalytics/DESCRIPTION 2014-04-18 15:05:31 UTC (rev 3373)
@@ -12,7 +12,7 @@
R (>= 2.14.0),
zoo,
xts (>= 0.8),
- PerformanceAnalytics (>= 1.0.0)
+ PerformanceAnalytics (>= 1.1.4)
Suggests:
quantmod,
DEoptim(>= 2.2.1),
Modified: pkg/PortfolioAnalytics/vignettes/risk_budget_optimization.Rnw
===================================================================
--- pkg/PortfolioAnalytics/vignettes/risk_budget_optimization.Rnw 2014-04-15 19:06:04 UTC (rev 3372)
+++ pkg/PortfolioAnalytics/vignettes/risk_budget_optimization.Rnw 2014-04-18 15:05:31 UTC (rev 3373)
@@ -316,12 +316,11 @@
As an example, consider the minimum CVaR concentration portfolio, with estimation from inception and monthly rebalancing. Since we require a minimum estimation length of total number of observations -1, we can optimize the portfolio only for the last two months.
<>=
-library(iterators)
set.seed(1234)
out <- optimize.portfolio.rebalancing(R=indexes, portfolio=ObjSpec,
optimize_method="DEoptim", search_size=5000,
- rebalance_on="months",
- training_period=nrow(indexes)-10,
+ rebalance_on="quarters",
+ training_period=nrow(indexes)-12,
traceDE=0)
@
From noreply at r-forge.r-project.org Sat Apr 19 06:03:18 2014
From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org)
Date: Sat, 19 Apr 2014 06:03:18 +0200 (CEST)
Subject: [Returnanalytics-commits] r3374 - pkg/PortfolioAnalytics/inst/tests
Message-ID: <20140419040319.3DEAA187558@r-forge.r-project.org>
Author: rossbennett34
Date: 2014-04-19 06:03:15 +0200 (Sat, 19 Apr 2014)
New Revision: 3374
Added:
pkg/PortfolioAnalytics/inst/tests/test_cplex_gmv.R
pkg/PortfolioAnalytics/inst/tests/test_cplex_maxMean.R
pkg/PortfolioAnalytics/inst/tests/test_cplex_minES.R
pkg/PortfolioAnalytics/inst/tests/test_cplex_qu.R
pkg/PortfolioAnalytics/inst/tests/test_glpk_maxMean.R
pkg/PortfolioAnalytics/inst/tests/test_glpk_minES.R
pkg/PortfolioAnalytics/inst/tests/test_qp_gmv.R
pkg/PortfolioAnalytics/inst/tests/test_qp_qu.R
Removed:
pkg/PortfolioAnalytics/inst/tests/test_roi_max_ret.R
pkg/PortfolioAnalytics/inst/tests/test_roi_min_etl.R
pkg/PortfolioAnalytics/inst/tests/test_roi_min_var.R
pkg/PortfolioAnalytics/inst/tests/test_roi_qu.R
Log:
Removing bad test files and adding improved test files. Specifically testing output of PortfolioAnalytics with output of solver (e.g. PortfolioAnalytics using ROI.plugin.glpk against using Rglpk directly)
Added: pkg/PortfolioAnalytics/inst/tests/test_cplex_gmv.R
===================================================================
--- pkg/PortfolioAnalytics/inst/tests/test_cplex_gmv.R (rev 0)
+++ pkg/PortfolioAnalytics/inst/tests/test_cplex_gmv.R 2014-04-19 04:03:15 UTC (rev 3374)
@@ -0,0 +1,166 @@
+library(PortfolioAnalytics)
+library(Rcplex)
+library(ROI)
+library(ROI.plugin.cplex)
+library(testthat)
+
+# Test that PortfolioAnalytics with ROI.plugin.cplex solutions equal Rcplex solutions
+context("GMV Portfolios: PortfolioAnalytics with ROI.plugin.cplex and Rcplex")
+
+# args(Rcplex)
+# ?Rcplex
+
+##### Data #####
+data(edhec)
+R <- edhec[, 1:5]
+funds <- colnames(R)
+m <- ncol(R)
+
+##### Parameters #####
+portf <- portfolio.spec(funds)
+portf <- add.constraint(portf, type="full_investment")
+portf <- add.constraint(portf, type="box", min=-Inf, max=Inf)
+portf <- add.objective(portf, type="risk", name="var")
+
+# Quadratic part of objective function
+objQ <- 2 * cov(R)
+
+# Linear part of objective function
+objL <- rep(0, m)
+
+# Constraints matrix
+Amat <- matrix(1, nrow=1, ncol=m)
+
+# right hand side of constraints
+rhs <- 1
+
+# direction of inequality of constraints
+dir <- "E"
+
+##### Unconstrained #####
+# Upper and lower bounds (i.e. box constraints)
+# Rcplex bounds
+lb <- rep(-Inf, m)
+ub <- rep(Inf, m)
+
+# Solve optimization with Rcplex
+opt.rcplex <- Rcplex(cvec=objL, Amat=Amat, bvec=rhs, Qmat=objQ, lb=lb, ub=ub,
+ sense=dir, control=list(trace=0))
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="cplex")
+weights <- as.numeric(extractWeights(opt.pa))
+
+test_that("Unconstrained: PortfolioAnalytics and Rcplex solution weights are equal", {
+ expect_that(weights, equals(opt.rcplex$xopt))
+})
+
+test_that("Unconstrained: PortfolioAnalytics and Rcplex solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.rcplex$obj))
+})
+
+##### Long Only #####
+# Upper and lower bounds (i.e. box constraints)
+# Rcplex bounds
+lb <- rep(0, m)
+ub <- rep(1, m)
+
+# Update box constraints in portfolio
+portf$constraints[[2]]$min <- lb
+portf$constraints[[2]]$max <- ub
+
+# Solve optimization with Rcplex
+opt.rcplex <- Rcplex(cvec=objL, Amat=Amat, bvec=rhs, Qmat=objQ, lb=lb, ub=ub,
+ sense=dir, control=list(trace=0))
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="cplex")
+weights <- as.numeric(extractWeights(opt.pa))
+
+test_that("Long Only: PortfolioAnalytics and Rcplex solution weights are equal", {
+ expect_that(weights, equals(opt.rcplex$xopt))
+})
+
+test_that("Long Only: PortfolioAnalytics bounds are respected", {
+ expect_that(all(weights >= lb) & all(weights <= ub), is_true())
+})
+
+test_that("Long Only: Rcplex bounds are respected", {
+ expect_that(all(opt.rcplex$xopt >= lb) & all(opt.rcplex$xopt <= ub), is_true())
+})
+
+test_that("Long Only: PortfolioAnalytics and Rcplex solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.rcplex$obj))
+})
+
+##### Box #####
+# Upper and lower bounds (i.e. box constraints)
+# Rcplex bounds
+lb <- rep(0.05, m)
+ub <- rep(0.55, m)
+
+# Update box constraints in portfolio
+portf$constraints[[2]]$min <- lb
+portf$constraints[[2]]$max <- ub
+
+# Solve optimization with Rcplex
+opt.rcplex <- Rcplex(cvec=objL, Amat=Amat, bvec=rhs, Qmat=objQ, lb=lb, ub=ub,
+ sense=dir, control=list(trace=0))
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="cplex")
+weights <- as.numeric(extractWeights(opt.pa))
+
+
+test_that("Box: PortfolioAnalytics and Rcplex solution weights are equal", {
+ expect_that(weights, equals(opt.rcplex$xopt))
+})
+
+test_that("Box: PortfolioAnalytics bounds are respected", {
+ expect_that(all(weights >= lb) & all(weights <= ub), is_true())
+})
+
+test_that("Box: Rcplex bounds are respected", {
+ expect_that(all(opt.rcplex$xopt >= lb) & all(opt.rcplex$xopt <= ub), is_true())
+})
+
+test_that("Box: PortfolioAnalytics and Rcplex solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.rcplex$obj))
+})
+
+##### Box with Shorting #####
+# Upper and lower bounds (i.e. box constraints)
+# Rcplex bounds
+lb <- rep(-0.05, m)
+ub <- rep(0.55, m)
+
+# Update box constraints in portfolio
+portf$constraints[[2]]$min <- lb
+portf$constraints[[2]]$max <- ub
+
+# Solve optimization with Rcplex
+opt.rcplex <- Rcplex(cvec=objL, Amat=Amat, bvec=rhs, Qmat=objQ, lb=lb, ub=ub,
+ sense=dir, control=list(trace=0))
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="cplex")
+weights <- as.numeric(extractWeights(opt.pa))
+
+
+test_that("Box with Shorting: PortfolioAnalytics and Rcplex solution weights are equal", {
+ expect_that(weights, equals(opt.rcplex$xopt))
+})
+
+test_that("Box with Shorting: PortfolioAnalytics bounds are respected", {
+ expect_that(all(weights >= lb) & all(weights <= ub), is_true())
+})
+
+test_that("Box with Shorting: Rcplex bounds are respected", {
+ expect_that(all(opt.rcplex$xopt >= lb) & all(opt.rcplex$xopt <= ub), is_true())
+})
+
+test_that("Box with Shorting: PortfolioAnalytics and Rcplex solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.rcplex$obj))
+})
+
+Rcplex.close()
Added: pkg/PortfolioAnalytics/inst/tests/test_cplex_maxMean.R
===================================================================
--- pkg/PortfolioAnalytics/inst/tests/test_cplex_maxMean.R (rev 0)
+++ pkg/PortfolioAnalytics/inst/tests/test_cplex_maxMean.R 2014-04-19 04:03:15 UTC (rev 3374)
@@ -0,0 +1,140 @@
+library(PortfolioAnalytics)
+library(Rcplex)
+library(ROI)
+library(ROI.plugin.cplex)
+library(testthat)
+
+# Test that ROI.plugin.cplex solutions equal Rcplex solutions
+context("Maximum Mean Return Portfolios: PortfolioAnalytics with ROI.plugin.cplex and Rcplex")
+
+# args(Rcplex)
+# ?Rcplex
+
+##### Data #####
+data(edhec)
+R <- edhec[, 1:5]
+funds <- colnames(R)
+m <- ncol(R)
+
+##### Parameters #####
+portf <- portfolio.spec(funds)
+portf <- add.constraint(portf, type="full_investment")
+portf <- add.constraint(portf, type="box", min=0, max=1)
+portf <- add.objective(portf, type="return", name="mean")
+
+# Quadratic part of objective function
+objQ <- NULL
+
+# Linear part of objective function
+objL <- -colMeans(R)
+
+# Constraints matrix
+Amat <- matrix(1, nrow=1, ncol=m)
+
+# right hand side of constraints
+rhs <- 1
+
+# direction of inequality of constraints
+dir <- "E"
+
+
+##### Long Only #####
+# Upper and lower bounds (i.e. box constraints)
+# Rcplex bounds
+lb <- rep(0, m)
+ub <- rep(1, m)
+
+# Solve optimization with Rcplex
+opt.rcplex <- Rcplex(cvec=objL, Amat=Amat, bvec=rhs, Qmat=objQ, lb=lb, ub=ub,
+ sense=dir, control=list(trace=0))
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="cplex")
+weights <- as.numeric(extractWeights(opt.pa))
+
+test_that("Long Only: PortfolioAnalytics and Rcplex solution weights are equal", {
+ expect_that(weights, equals(opt.rcplex$xopt))
+})
+
+test_that("Long Only: PortfolioAnalytics bounds are respected", {
+ expect_that(all(weights >= lb) & all(weights <= ub), is_true())
+})
+
+test_that("Long Only: Rcplex bounds are respected", {
+ expect_that(all(opt.rcplex$xopt >= lb) & all(opt.rcplex$xopt <= ub), is_true())
+})
+
+test_that("Long Only: PortfolioAnalytics and Rcplex solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.rcplex$obj))
+})
+
+##### Box #####
+# Upper and lower bounds (i.e. box constraints)
+# Rcplex bounds
+lb <- rep(0.05, m)
+ub <- rep(0.55, m)
+
+# Update box constraints in portfolio
+portf$constraints[[2]]$min <- lb
+portf$constraints[[2]]$max <- ub
+
+# Solve optimization with Rcplex
+opt.rcplex <- Rcplex(cvec=objL, Amat=Amat, bvec=rhs, Qmat=objQ, lb=lb, ub=ub,
+ sense=dir, control=list(trace=0))
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="cplex")
+weights <- as.numeric(extractWeights(opt.pa))
+
+test_that("Box: PortfolioAnalytics and Rcplex solution weights are equal", {
+ expect_that(weights, equals(opt.rcplex$xopt))
+})
+
+test_that("Box: PortfolioAnalytics bounds are respected", {
+ expect_that(all(weights >= lb) & all(weights <= ub), is_true())
+})
+
+test_that("Box: Rcplex bounds are respected", {
+ expect_that(all(opt.rcplex$xopt >= lb) & all(opt.rcplex$xopt <= ub), is_true())
+})
+
+test_that("Box: PortfolioAnalytics and Rcplex solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.rcplex$obj))
+})
+
+##### Box with Shorting #####
+# Upper and lower bounds (i.e. box constraints)
+# Rcplex bounds
+lb <- rep(-0.05, m)
+ub <- rep(0.55, m)
+
+# Update box constraints in portfolio
+portf$constraints[[2]]$min <- lb
+portf$constraints[[2]]$max <- ub
+
+# Solve optimization with Rcplex
+opt.rcplex <- Rcplex(cvec=objL, Amat=Amat, bvec=rhs, Qmat=objQ, lb=lb, ub=ub,
+ sense=dir, control=list(trace=0))
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="cplex")
+weights <- as.numeric(extractWeights(opt.pa))
+
+test_that("Box with Shorting: PortfolioAnalytics and Rcplex solution weights are equal", {
+ expect_that(weights, equals(opt.rcplex$xopt))
+})
+
+test_that("Box with Shorting: PortfolioAnalytics bounds are respected", {
+ expect_that(all(weights >= lb) & all(weights <= ub), is_true())
+})
+
+test_that("Box with Shorting: Rcplex bounds are respected", {
+ expect_that(all(opt.rcplex$xopt >= lb) & all(opt.rcplex$xopt <= ub), is_true())
+})
+
+test_that("Box with Shorting: PortfolioAnalytics and Rcplex solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.rcplex$obj))
+})
+
+Rcplex.close()
+
Added: pkg/PortfolioAnalytics/inst/tests/test_cplex_minES.R
===================================================================
--- pkg/PortfolioAnalytics/inst/tests/test_cplex_minES.R (rev 0)
+++ pkg/PortfolioAnalytics/inst/tests/test_cplex_minES.R 2014-04-19 04:03:15 UTC (rev 3374)
@@ -0,0 +1,184 @@
+library(PortfolioAnalytics)
+library(Rcplex)
+library(ROI)
+library(ROI.plugin.cplex)
+library(testthat)
+
+# Test that ROI.plugin.cplex solutions equal Rcplex solutions
+context("Minimum ES Portfolios: PortfolioAnalytics with ROI.plugin.cplex and Rcplex")
+
+# args(Rcplex)
+# ?Rcplex
+
+##### Data #####
+data(edhec)
+R <- edhec[, 1:5]
+funds <- colnames(R)
+
+##### Parameters #####
+m <- ncol(R)
+n <- nrow(R)
+alpha <- 0.05
+
+portf <- portfolio.spec(funds)
+portf <- add.constraint(portf, type="full_investment")
+portf <- add.constraint(portf, type="box", min=-Inf, max=Inf)
+portf <- add.objective(portf, type="risk", name="ES", arguments=list(p=1-alpha))
+
+# Quadratic part of objective function
+objQ <- NULL
+
+# Linear part of objective function
+objL <- c(rep(0, m), rep(1 / (alpha * n), n), 1)
+
+# Constraints matrix
+Amat <- cbind(rbind(1, zoo::coredata(R)),
+ rbind(0, cbind(diag(n), 1)))
+
+# right hand side of constraints
+rhs <- c(1, rep(0, n))
+
+# direction of inequality of constraints
+dir <- c("E", rep("G", n))
+
+##### Unconstrained #####
+# Upper and lower bounds (i.e. box constraints)
+# Rcplex bounds
+min_box <- rep(-Inf, m)
+max_box <- rep(Inf, m)
+
+lb <- c(min_box, rep(0, n), -1)
+ub <- c(max_box, rep(Inf, n), 1)
+
+
+# Solve optimization with Rcplex
+opt.rcplex <- Rcplex(cvec=objL, Amat=Amat, bvec=rhs, Qmat=objQ, lb=lb, ub=ub,
+ sense=dir, control=list(trace=0))
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="cplex")
+weights <- as.numeric(extractWeights(opt.pa))
+
+
+test_that("Unconstrained: PortfolioAnalytics and Rcplex solution weights are equal", {
+ expect_that(weights, equals(opt.rcplex$xopt[1:m]))
+})
+
+test_that("Unconstrained: PortfolioAnalytics and Rcplex solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.rcplex$obj))
+})
+
+
+##### Long Only #####
+# Upper and lower bounds (i.e. box constraints)
+# Rcplex bounds
+min_box <- rep(0, m)
+max_box <- rep(1, m)
+
+lb <- c(min_box, rep(0, n), -1)
+ub <- c(max_box, rep(Inf, n), 1)
+
+# Update box constraints in portfolio
+portf$constraints[[2]]$min <- min_box
+portf$constraints[[2]]$max <- max_box
+
+# Solve optimization with Rcplex
+opt.rcplex <- Rcplex(cvec=objL, Amat=Amat, bvec=rhs, Qmat=objQ, lb=lb, ub=ub,
+ sense=dir, control=list(trace=0))
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="cplex")
+weights <- as.numeric(extractWeights(opt.pa))
+
+test_that("Long Only: PortfolioAnalytics and Rcplex solution weights are equal", {
+ expect_that(weights, equals(opt.rcplex$xopt[1:m]))
+})
+
+test_that("Long Only: PortfolioAnalytics bounds are respected", {
+ expect_that(all(weights >= min_box) & all(weights <= max_box), is_true())
+})
+
+test_that("Long Only: Rcplex bounds are respected", {
+ expect_that(all(opt.rcplex$xopt[1:m] >= min_box) & all(opt.rcplex$xopt[1:m] <= max_box), is_true())
+})
+
+test_that("Long Only: PortfolioAnalytics and Rcplex solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.rcplex$obj))
+})
+
+##### Box #####
+# Upper and lower bounds (i.e. box constraints)
+# Rcplex bounds
+min_box <- rep(0.05, m)
+max_box <- rep(0.55, m)
+
+lb <- c(min_box, rep(0, n), -1)
+ub <- c(max_box, rep(Inf, n), 1)
+
+# Update box constraints in portfolio
+portf$constraints[[2]]$min <- min_box
+portf$constraints[[2]]$max <- max_box
+
+# Solve optimization with Rcplex
+opt.rcplex <- Rcplex(cvec=objL, Amat=Amat, bvec=rhs, Qmat=objQ, lb=lb, ub=ub,
+ sense=dir, control=list(trace=0))
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="cplex")
+weights <- as.numeric(extractWeights(opt.pa))
+
+test_that("Box: PortfolioAnalytics and Rcplex solution weights are equal", {
+ expect_that(weights, equals(opt.rcplex$xopt[1:m]))
+})
+
+test_that("Box: PortfolioAnalytics bounds are respected", {
+ expect_that(all(weights >= min_box) & all(weights <= max_box), is_true())
+})
+
+test_that("Box: Rcplex bounds are respected", {
+ expect_that(all(opt.rcplex$xopt[1:m] >= min_box) & all(opt.rcplex$xopt[1:m] <= max_box), is_true())
+})
+
+test_that("Box: PortfolioAnalytics and Rcplex solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.rcplex$obj))
+})
+
+##### Box with Shorting #####
+# Upper and lower bounds (i.e. box constraints)
+# Rcplex bounds
+min_box <- rep(-0.05, m)
+max_box <- rep(0.55, m)
+
+lb <- c(min_box, rep(0, n), -1)
+ub <- c(max_box, rep(Inf, n), 1)
+
+# Update box constraints in portfolio
+portf$constraints[[2]]$min <- min_box
+portf$constraints[[2]]$max <- max_box
+
+# Solve optimization with Rcplex
+opt.rcplex <- Rcplex(cvec=objL, Amat=Amat, bvec=rhs, Qmat=objQ, lb=lb, ub=ub,
+ sense=dir, control=list(trace=0))
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="cplex")
+weights <- as.numeric(extractWeights(opt.pa))
+
+test_that("Box with Shorting: PortfolioAnalytics and Rcplex solution weights are equal", {
+ expect_that(weights, equals(opt.rcplex$xopt[1:m]))
+})
+
+test_that("Box with Shorting: PortfolioAnalytics bounds are respected", {
+ expect_that(all(weights >= min_box) & all(weights <= max_box), is_true())
+})
+
+test_that("Box with Shorting: Rcplex bounds are respected", {
+ expect_that(all(opt.rcplex$xopt[1:m] >= min_box) & all(opt.rcplex$xopt[1:m] <= max_box), is_true())
+})
+
+test_that("Box with Shorting: PortfolioAnalytics and Rcplex solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.rcplex$obj))
+})
+
+Rcplex.close()
+
Added: pkg/PortfolioAnalytics/inst/tests/test_cplex_qu.R
===================================================================
--- pkg/PortfolioAnalytics/inst/tests/test_cplex_qu.R (rev 0)
+++ pkg/PortfolioAnalytics/inst/tests/test_cplex_qu.R 2014-04-19 04:03:15 UTC (rev 3374)
@@ -0,0 +1,171 @@
+library(PortfolioAnalytics)
+library(Rcplex)
+library(ROI)
+library(ROI.plugin.cplex)
+library(testthat)
+
+# Test that PortfolioAnalytics with ROI.plugin.cplex solutions equal Rcplex solutions
+context("Maximum Quadratic Utility Portfolios: PortfolioAnalytics with ROI.plugin.cplex and Rcplex")
+
+# args(Rcplex)
+# ?Rcplex
+
+##### Data #####
+data(edhec)
+R <- edhec[, 1:5]
+funds <- colnames(R)
+m <- ncol(R)
+
+##### Parameters #####
+
+# risk aversion parameter
+lambda <- 1
+
+portf <- portfolio.spec(funds)
+portf <- add.constraint(portf, type="full_investment")
+portf <- add.constraint(portf, type="box", min=-Inf, max=Inf)
+portf <- add.objective(portf, type="risk", name="var", risk_aversion=lambda)
+portf <- add.objective(portf, type="return", name="mean")
+
+# Quadratic part of objective function
+objQ <- lambda * 2 * cov(R)
+
+# Linear part of objective function
+objL <- -colMeans(R)
+
+# Constraints matrix
+Amat <- matrix(1, nrow=1, ncol=m)
+
+# right hand side of constraints
+rhs <- 1
+
+# direction of inequality of constraints
+dir <- "E"
+
+##### Unconstrained #####
+# Upper and lower bounds (i.e. box constraints)
+# Rcplex bounds
+lb <- rep(-Inf, m)
+ub <- rep(Inf, m)
+
+# Solve optimization with Rcplex
+opt.rcplex <- Rcplex(cvec=objL, Amat=Amat, bvec=rhs, Qmat=objQ, lb=lb, ub=ub,
+ sense=dir, control=list(trace=0))
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="cplex")
+weights <- as.numeric(extractWeights(opt.pa))
+
+test_that("Unconstrained: PortfolioAnalytics and Rcplex solution weights are equal", {
+ expect_that(weights, equals(opt.rcplex$xopt))
+})
+
+test_that("Unconstrained: PortfolioAnalytics and Rcplex solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.rcplex$obj))
+})
+
+##### Long Only #####
+# Upper and lower bounds (i.e. box constraints)
+# Rcplex bounds
+lb <- rep(0, m)
+ub <- rep(1, m)
+
+# Update box constraints in portfolio
+portf$constraints[[2]]$min <- lb
+portf$constraints[[2]]$max <- ub
+
+# Solve optimization with Rcplex
+opt.rcplex <- Rcplex(cvec=objL, Amat=Amat, bvec=rhs, Qmat=objQ, lb=lb, ub=ub,
+ sense=dir, control=list(trace=0))
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="cplex")
+weights <- as.numeric(extractWeights(opt.pa))
+
+test_that("Long Only: PortfolioAnalytics and Rcplex solution weights are equal", {
+ expect_that(weights, equals(opt.rcplex$xopt))
+})
+
+test_that("Long Only: PortfolioAnalytics bounds are respected", {
+ expect_that(all(weights >= lb) & all(weights <= ub), is_true())
+})
+
+test_that("Long Only: Rcplex bounds are respected", {
+ expect_that(all(opt.rcplex$xopt >= lb) & all(opt.rcplex$xopt <= ub), is_true())
+})
+
+test_that("Long Only: PortfolioAnalytics and Rcplex solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.rcplex$obj))
+})
+
+##### Box #####
+# Upper and lower bounds (i.e. box constraints)
+# Rcplex bounds
+lb <- rep(0.05, m)
+ub <- rep(0.55, m)
+
+# Update box constraints in portfolio
+portf$constraints[[2]]$min <- lb
+portf$constraints[[2]]$max <- ub
+
+# Solve optimization with Rcplex
+opt.rcplex <- Rcplex(cvec=objL, Amat=Amat, bvec=rhs, Qmat=objQ, lb=lb, ub=ub,
+ sense=dir, control=list(trace=0))
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="cplex")
+weights <- as.numeric(extractWeights(opt.pa))
+
+
+test_that("Box: PortfolioAnalytics and Rcplex solution weights are equal", {
+ expect_that(weights, equals(opt.rcplex$xopt))
+})
+
+test_that("Box: PortfolioAnalytics bounds are respected", {
+ expect_that(all(weights >= lb) & all(weights <= ub), is_true())
+})
+
+test_that("Box: Rcplex bounds are respected", {
+ expect_that(all(opt.rcplex$xopt >= lb) & all(opt.rcplex$xopt <= ub), is_true())
+})
+
+test_that("Box: PortfolioAnalytics and Rcplex solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.rcplex$obj))
+})
+
+##### Box with Shorting #####
+# Upper and lower bounds (i.e. box constraints)
+# Rcplex bounds
+lb <- rep(-0.05, m)
+ub <- rep(0.55, m)
+
+# Update box constraints in portfolio
+portf$constraints[[2]]$min <- lb
+portf$constraints[[2]]$max <- ub
+
+# Solve optimization with Rcplex
+opt.rcplex <- Rcplex(cvec=objL, Amat=Amat, bvec=rhs, Qmat=objQ, lb=lb, ub=ub,
+ sense=dir, control=list(trace=0))
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="cplex")
+weights <- as.numeric(extractWeights(opt.pa))
+
+
+test_that("Box with Shorting: PortfolioAnalytics and Rcplex solution weights are equal", {
+ expect_that(weights, equals(opt.rcplex$xopt))
+})
+
+test_that("Box with Shorting: PortfolioAnalytics bounds are respected", {
+ expect_that(all(weights >= lb) & all(weights <= ub), is_true())
+})
+
+test_that("Box with Shorting: Rcplex bounds are respected", {
+ expect_that(all(opt.rcplex$xopt >= lb) & all(opt.rcplex$xopt <= ub), is_true())
+})
+
+test_that("Box with Shorting: PortfolioAnalytics and Rcplex solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.rcplex$obj))
+})
+
+Rcplex.close()
Added: pkg/PortfolioAnalytics/inst/tests/test_glpk_maxMean.R
===================================================================
--- pkg/PortfolioAnalytics/inst/tests/test_glpk_maxMean.R (rev 0)
+++ pkg/PortfolioAnalytics/inst/tests/test_glpk_maxMean.R 2014-04-19 04:03:15 UTC (rev 3374)
@@ -0,0 +1,141 @@
+library(PortfolioAnalytics)
+library(ROI)
+library(ROI.plugin.glpk)
+library(Rglpk)
+library(testthat)
+
+# Test that ROI.plugin.glpk solutions equal Rglpk solutions
+context("Maximum Mean Return Portfolios: PortfolioAnalytics with ROI.plugin.glpk and Rglpk")
+
+
+##### Data #####
+data(edhec)
+R <- edhec[, 1:5]
+funds <- colnames(R)
+
+##### Parameters #####
+m <- ncol(R)
+
+portf <- portfolio.spec(funds)
+portf <- add.constraint(portf, type="full_investment")
+portf <- add.constraint(portf, type="box", min=-Inf, max=Inf)
+portf <- add.objective(portf, type="return", name="mean")
+
+# Linear part of objective function
+objL <- -colMeans(R)
+
+# Constraints matrix
+Amat <- matrix(1, nrow=1, ncol=m)
+
+# right hand side of constraints
+rhs <- 1
+
+# direction of inequality of constraints
+dir <- "=="
+
+##### Long Only #####
+# Upper and lower bounds (i.e. box constraints)
+lb <- rep(0, m)
+ub <- rep(1, m)
+
+bnds <- list(lower = list(ind = seq.int(1L, m), val = lb),
+ upper = list(ind = seq.int(1L, m), val = ub))
+
+# Update box constraints in portfolio
+portf$constraints[[2]]$min <- lb
+portf$constraints[[2]]$max <- ub
+
+# Solve optimization with Rglpk
+opt.glpk <- Rglpk_solve_LP(obj=objL, mat=Amat, dir=dir, rhs=rhs, bounds=bnds)
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="glpk")
+weights <- as.numeric(extractWeights(opt.pa))
+
+test_that("Long Only: PortfolioAnalytics and Rglpk solution weights are equal", {
+ expect_that(weights, equals(opt.glpk$solution[1:m]))
+})
+
+test_that("Long Only: PortfolioAnalytics bounds are respected", {
+ expect_that(all(weights >= lb) & all(weights <= ub), is_true())
+})
+
+test_that("Long Only: Rglpk bounds are respected", {
+ expect_that(all(opt.glpk$solution[1:m] >= lb) & all(opt.glpk$solution[1:m] <= ub), is_true())
+})
+
+test_that("Long Only: PortfolioAnalytics and Rglpk solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.glpk$optimum))
+})
+
+##### Box #####
+# Upper and lower bounds (i.e. box constraints)
+lb <- rep(0.05, m)
+ub <- rep(0.55, m)
+
+bnds <- list(lower = list(ind = seq.int(1L, m), val = lb),
+ upper = list(ind = seq.int(1L, m), val = ub))
+
+# Update box constraints in portfolio
+portf$constraints[[2]]$min <- lb
+portf$constraints[[2]]$max <- ub
+
+# Solve optimization with Rglpk
+opt.glpk <- Rglpk_solve_LP(obj=objL, mat=Amat, dir=dir, rhs=rhs, bounds=bnds)
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="glpk")
+weights <- as.numeric(extractWeights(opt.pa))
+
+test_that("Box: PortfolioAnalytics and Rglpk solution weights are equal", {
+ expect_that(weights, equals(opt.glpk$solution[1:m]))
+})
+
+test_that("Box: PortfolioAnalytics bounds are respected", {
+ expect_that(all(weights >= lb) & all(weights <= ub), is_true())
+})
+
+test_that("Box: Rglpk bounds are respected", {
+ expect_that(all(opt.glpk$solution[1:m] >= lb) & all(opt.glpk$solution[1:m] <= ub), is_true())
+})
+
+test_that("Box: PortfolioAnalytics and Rglpk solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.glpk$optimum))
+})
+
+##### Box with Shorting #####
+# Upper and lower bounds (i.e. box constraints)
+lb <- rep(-0.05, m)
+ub <- rep(0.55, m)
+
+bnds <- list(lower = list(ind = seq.int(1L, m), val = lb),
+ upper = list(ind = seq.int(1L, m), val = ub))
+
+# Update box constraints in portfolio
+portf$constraints[[2]]$min <- lb
+portf$constraints[[2]]$max <- ub
+
+# Solve optimization with Rglpk
+opt.glpk <- Rglpk_solve_LP(obj=objL, mat=Amat, dir=dir, rhs=rhs, bounds=bnds)
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="glpk")
+weights <- as.numeric(extractWeights(opt.pa))
+
+test_that("Box with Shorting: PortfolioAnalytics and Rglpk solution weights are equal", {
+ expect_that(weights, equals(opt.glpk$solution[1:m]))
+})
+
+test_that("Box with Shorting: PortfolioAnalytics bounds are respected", {
+ expect_that(all(weights >= lb) & all(weights <= ub), is_true())
+})
+
+test_that("Box with Shorting: Rglpk bounds are respected", {
+ expect_that(all(opt.glpk$solution[1:m] >= lb) & all(opt.glpk$solution[1:m] <= ub), is_true())
+})
+
+test_that("Box with Shorting: PortfolioAnalytics and Rglpk solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.glpk$optimum))
+})
+
+
Added: pkg/PortfolioAnalytics/inst/tests/test_glpk_minES.R
===================================================================
--- pkg/PortfolioAnalytics/inst/tests/test_glpk_minES.R (rev 0)
+++ pkg/PortfolioAnalytics/inst/tests/test_glpk_minES.R 2014-04-19 04:03:15 UTC (rev 3374)
@@ -0,0 +1,153 @@
+library(PortfolioAnalytics)
+library(ROI)
+library(ROI.plugin.glpk)
+library(Rglpk)
+library(testthat)
+
+# Test that ROI.plugin.glpk solutions equal Rglpk solutions
+context("Minimum ES Portfolios: PortfolioAnalytics with ROI.plugin.glpk and Rglpk")
+
+
+##### Data #####
+data(edhec)
+R <- edhec[, 1:5]
+funds <- colnames(R)
+
+##### Parameters #####
+m <- ncol(R)
+n <- nrow(R)
+alpha <- 0.05
+
+portf <- portfolio.spec(funds)
+portf <- add.constraint(portf, type="full_investment")
+portf <- add.constraint(portf, type="box", min=-Inf, max=Inf)
+portf <- add.objective(portf, type="risk", name="ES", arguments=list(p=1-alpha))
+
+# Linear part of objective function
+objL <- c(rep(0, m), rep(1 / (alpha * n), n), 1)
+
+# Constraints matrix
+Amat <- cbind(rbind(1, zoo::coredata(R)),
+ rbind(0, cbind(diag(n), 1)))
+
+# right hand side of constraints
+rhs <- c(1, rep(0, n))
+
+# direction of inequality of constraints
+dir <- c("==", rep(">=", n))
+
+##### Long Only #####
+# Upper and lower bounds (i.e. box constraints)
+min_box <- rep(0, m)
+max_box <- rep(1, m)
+
+lb <- c(min_box, rep(0, n), -1)
+ub <- c(max_box, rep(Inf, n), 1)
+
+bnds <- list(lower = list(ind = seq.int(1L, m+n+1), val = lb),
+ upper = list(ind = seq.int(1L, m+n+1), val = ub))
+
+# Update box constraints in portfolio
+portf$constraints[[2]]$min <- min_box
+portf$constraints[[2]]$max <- max_box
+
+# Solve optimization with Rglpk
+opt.glpk <- Rglpk_solve_LP(obj=objL, mat=Amat, dir=dir, rhs=rhs, bounds=bnds)
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="glpk")
+weights <- as.numeric(extractWeights(opt.pa))
+
+test_that("Long Only: PortfolioAnalytics and Rglpk solution weights are equal", {
+ expect_that(weights, equals(opt.glpk$solution[1:m]))
+})
+
+test_that("Long Only: PortfolioAnalytics bounds are respected", {
+ expect_that(all(weights >= min_box) & all(weights <= max_box), is_true())
+})
+
+test_that("Long Only: Rglpk bounds are respected", {
+ expect_that(all(opt.glpk$solution[1:m] >= min_box) & all(opt.glpk$solution[1:m] <= max_box), is_true())
+})
+
+test_that("Long Only: PortfolioAnalytics and Rglpk solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.glpk$optimum))
+})
+
+##### Box #####
+# Upper and lower bounds (i.e. box constraints)
+min_box <- rep(0.05, m)
+max_box <- rep(0.55, m)
+
+lb <- c(min_box, rep(0, n), -1)
+ub <- c(max_box, rep(Inf, n), 1)
+
+bnds <- list(lower = list(ind = seq.int(1L, m+n+1), val = lb),
+ upper = list(ind = seq.int(1L, m+n+1), val = ub))
+
+# Update box constraints in portfolio
+portf$constraints[[2]]$min <- min_box
+portf$constraints[[2]]$max <- max_box
+
+# Solve optimization with Rglpk
+opt.glpk <- Rglpk_solve_LP(obj=objL, mat=Amat, dir=dir, rhs=rhs, bounds=bnds)
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="glpk")
+weights <- as.numeric(extractWeights(opt.pa))
+
+test_that("Box: PortfolioAnalytics and Rglpk solution weights are equal", {
+ expect_that(weights, equals(opt.glpk$solution[1:m]))
+})
+
+test_that("Box: PortfolioAnalytics bounds are respected", {
+ expect_that(all(weights >= min_box) & all(weights <= max_box), is_true())
+})
+
+test_that("Box: Rglpk bounds are respected", {
+ expect_that(all(opt.glpk$solution[1:m] >= min_box) & all(opt.glpk$solution[1:m] <= max_box), is_true())
+})
+
+test_that("Box: PortfolioAnalytics and Rglpk solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.glpk$optimum))
+})
+
+##### Box with Shorting #####
+# Upper and lower bounds (i.e. box constraints)
+min_box <- rep(-0.05, m)
+max_box <- rep(0.55, m)
+
+lb <- c(min_box, rep(0, n), -1)
+ub <- c(max_box, rep(Inf, n), 1)
+
+bnds <- list(lower = list(ind = seq.int(1L, m+n+1), val = lb),
+ upper = list(ind = seq.int(1L, m+n+1), val = ub))
+
+# Update box constraints in portfolio
+portf$constraints[[2]]$min <- min_box
+portf$constraints[[2]]$max <- max_box
+
+# Solve optimization with Rglpk
+opt.glpk <- Rglpk_solve_LP(obj=objL, mat=Amat, dir=dir, rhs=rhs, bounds=bnds)
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="glpk")
+weights <- as.numeric(extractWeights(opt.pa))
+
+test_that("Box with Shorting: PortfolioAnalytics and Rglpk solution weights are equal", {
+ expect_that(weights, equals(opt.glpk$solution[1:m]))
+})
+
+test_that("Box with Shorting: PortfolioAnalytics bounds are respected", {
+ expect_that(all(weights >= min_box) & all(weights <= max_box), is_true())
+})
+
+test_that("Box with Shorting: Rglpk bounds are respected", {
+ expect_that(all(opt.glpk$solution[1:m] >= min_box) & all(opt.glpk$solution[1:m] <= max_box), is_true())
+})
+
+test_that("Box with Shorting: PortfolioAnalytics and Rglpk solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.glpk$optimum))
+})
+
+
Added: pkg/PortfolioAnalytics/inst/tests/test_qp_gmv.R
===================================================================
--- pkg/PortfolioAnalytics/inst/tests/test_qp_gmv.R (rev 0)
+++ pkg/PortfolioAnalytics/inst/tests/test_qp_gmv.R 2014-04-19 04:03:15 UTC (rev 3374)
@@ -0,0 +1,162 @@
+library(PortfolioAnalytics)
+library(ROI)
+library(ROI.plugin.quadprog)
+library(quadprog)
+library(testthat)
+
+# Test that PortfolioAnalytics with ROI.plugin.quadprog solutions equal quadprog solutions
+context("GMV Portfolios: PortfolioAnalytics with ROI.plugin.quadprog and quadprog")
+
+
+##### Data #####
+data(edhec)
+R <- edhec[, 1:5]
+funds <- colnames(R)
+m <- ncol(R)
+
+##### Parameters #####
+portf <- portfolio.spec(funds)
+portf <- add.constraint(portf, type="full_investment")
+portf <- add.constraint(portf, type="box", min=-Inf, max=Inf)
+portf <- add.objective(portf, type="risk", name="var")
+
+# Quadratic part of objective function
+objQ <- 2 * cov(R)
+
+# Linear part of objective function
+objL <- rep(0, m)
+
+# Constraints matrix
+Amat <- matrix(1, nrow=1, ncol=m)
+
+# right hand side of constraints
+rhs <- 1
+
+
+##### Unconstrained #####
+
+# Solve optimization with quadprog
+opt.qp <- solve.QP(Dmat=objQ, dvec=objL, Amat=t(Amat), bvec=rhs, meq=1)
+
+# Solve optimization with PortfolioAnalytics
+opt.pa <- optimize.portfolio(R, portf, optimize_method="quadprog")
+weights <- as.numeric(extractWeights(opt.pa))
+
+test_that("Unconstrained: PortfolioAnalytics and quadprog solution weights are equal", {
+ expect_that(weights, equals(opt.qp$solution))
+})
+
+test_that("Unconstrained: PortfolioAnalytics and quadprog solution objective values are equal", {
+ expect_that(opt.pa$out, equals(opt.qp$value))
+})
+
+##### Long Only #####
+# Upper and lower bounds (i.e. box constraints)
+lb <- rep(0, m)
+ub <- rep(1, m)
+
+Amat <- rbind(1, diag(m), -diag(m))
+rhs <- c(1, lb, -ub)
+
+# Update box constraints in portfolio
+portf$constraints[[2]]$min <- lb
+portf$constraints[[2]]$max <- ub
+
[TRUNCATED]
To get the complete diff run:
svnlook diff /svnroot/returnanalytics -r 3374
From noreply at r-forge.r-project.org Sun Apr 20 18:38:03 2014
From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org)
Date: Sun, 20 Apr 2014 18:38:03 +0200 (CEST)
Subject: [Returnanalytics-commits] r3375 - in pkg/PortfolioAnalytics: . R man
Message-ID: <20140420163803.6FA22186E01@r-forge.r-project.org>
Author: rossbennett34
Date: 2014-04-20 18:38:03 +0200 (Sun, 20 Apr 2014)
New Revision: 3375
Modified:
pkg/PortfolioAnalytics/DESCRIPTION
pkg/PortfolioAnalytics/R/optFUN.R
pkg/PortfolioAnalytics/R/optimize.portfolio.R
pkg/PortfolioAnalytics/man/etl_milp_opt.Rd
pkg/PortfolioAnalytics/man/etl_opt.Rd
pkg/PortfolioAnalytics/man/gmv_opt.Rd
pkg/PortfolioAnalytics/man/gmv_opt_ptc.Rd
pkg/PortfolioAnalytics/man/gmv_opt_toc.Rd
pkg/PortfolioAnalytics/man/maxret_milp_opt.Rd
pkg/PortfolioAnalytics/man/maxret_opt.Rd
Log:
Adding ROI.plugin.cplex to Suggests and support for control argument in ROI_solve
Modified: pkg/PortfolioAnalytics/DESCRIPTION
===================================================================
--- pkg/PortfolioAnalytics/DESCRIPTION 2014-04-19 04:03:15 UTC (rev 3374)
+++ pkg/PortfolioAnalytics/DESCRIPTION 2014-04-20 16:38:03 UTC (rev 3375)
@@ -25,6 +25,7 @@
ROI.plugin.glpk (>= 0.0.2),
ROI.plugin.quadprog (>= 0.0.2),
ROI.plugin.symphony (>= 0.0.2),
+ ROI.plugin.cplex (>= 0.0.2),
pso,
GenSA,
corpcor,
Modified: pkg/PortfolioAnalytics/R/optFUN.R
===================================================================
--- pkg/PortfolioAnalytics/R/optFUN.R 2014-04-19 04:03:15 UTC (rev 3374)
+++ pkg/PortfolioAnalytics/R/optFUN.R 2014-04-20 16:38:03 UTC (rev 3375)
@@ -13,10 +13,12 @@
#' @param lambda_hhi concentration aversion parameter
#' @param conc_groups list of vectors specifying the groups of the assets.
#' @param solver solver to use
+#' @param control list of solver control parameters
#' @author Ross Bennett
-gmv_opt <- function(R, constraints, moments, lambda, target, lambda_hhi, conc_groups, solver="quadprog"){
- stopifnot("package:ROI" %in% search() || require("ROI", quietly = TRUE))
- stopifnot("package:ROI.plugin.quadprog" %in% search() || require("ROI.plugin.quadprog", quietly = TRUE))
+gmv_opt <- function(R, constraints, moments, lambda, target, lambda_hhi, conc_groups, solver="quadprog", control=NULL){
+ stopifnot("package:ROI" %in% search() || require("ROI", quietly=TRUE))
+ plugin <- paste0("ROI.plugin.", solver)
+ stopifnot(paste0("package:", plugin) %in% search() || require(plugin, quietly=TRUE, character.only=TRUE))
# Check for cleaned returns in moments
if(!is.null(moments$cleanR)) R <- moments$cleanR
@@ -129,7 +131,7 @@
opt.prob <- OP(objective=ROI_objective,
constraints=L_constraint(L=Amat, dir=dir.vec, rhs=rhs.vec),
bounds=bnds)
- result <- try(ROI_solve(x=opt.prob, solver=solver), silent=TRUE)
+ result <- try(ROI_solve(x=opt.prob, solver=solver, control=control), silent=TRUE)
# result <- try(solve.QP(Dmat=Dmat, dvec=dvec, Amat=t(Amat), bvec=rhs.vec, meq=meq), silent=TRUE)
if(inherits(x=result, "try-error")) stop(paste("No solution found:", result))
@@ -171,10 +173,12 @@
#' @param moments object of moments computed based on objective functions
#' @param target target return value
#' @param solver solver to use
+#' @param control list of solver control parameters
#' @author Ross Bennett
-maxret_opt <- function(R, moments, constraints, target, solver="glpk"){
+maxret_opt <- function(R, moments, constraints, target, solver="glpk", control=NULL){
stopifnot("package:ROI" %in% search() || require("ROI",quietly = TRUE))
- stopifnot("package:ROI.plugin.glpk" %in% search() || require("ROI.plugin.glpk",quietly = TRUE))
+ plugin <- paste0("ROI.plugin.", solver)
+ stopifnot(paste0("package:", plugin) %in% search() || require(plugin, quietly=TRUE, character.only=TRUE))
# Check for cleaned returns in moments
if(!is.null(moments$cleanR)) R <- moments$cleanR
@@ -235,7 +239,8 @@
opt.prob <- OP(objective=ROI_objective,
constraints=L_constraint(L=Amat, dir=dir.vec, rhs=rhs.vec),
bounds=bnds)
- roi.result <- ROI_solve(x=opt.prob, solver=solver)
+ roi.result <- try(ROI_solve(x=opt.prob, solver=solver, control=control), silent=TRUE)
+ if(inherits(roi.result, "try-error")) stop(paste("No solution found:", roi.result))
# roi.result <- Rglpk_solve_LP(obj=objL, mat=Amat, dir=dir.vec, rhs=rhs.vec, bounds=bnds)
@@ -276,10 +281,12 @@
#' @param moments object of moments computed based on objective functions
#' @param target target return value
#' @param solver solver to use
+#' @param control list of solver control parameters
#' @author Ross Bennett
-maxret_milp_opt <- function(R, constraints, moments, target, solver="glpk"){
+maxret_milp_opt <- function(R, constraints, moments, target, solver="glpk", control=NULL){
stopifnot("package:ROI" %in% search() || require("ROI",quietly = TRUE))
- stopifnot("package:ROI.plugin.glpk" %in% search() || require("ROI.plugin.glpk",quietly = TRUE))
+ plugin <- paste0("ROI.plugin.", solver)
+ stopifnot(paste0("package:", plugin) %in% search() || require(plugin, quietly=TRUE, character.only=TRUE))
# Check for cleaned returns in moments
if(!is.null(moments$cleanR)) R <- moments$cleanR
@@ -369,7 +376,7 @@
opt.prob <- OP(objective=ROI_objective,
constraints=L_constraint(L=Amat, dir=dir, rhs=rhs),
bounds=bnds, types=types)
- roi.result <- try(ROI_solve(x=opt.prob, solver=solver), silent=TRUE)
+ roi.result <- try(ROI_solve(x=opt.prob, solver=solver, control=control), silent=TRUE)
if(inherits(roi.result, "try-error")) stop(paste("No solution found:", roi.result))
# Weights
@@ -400,10 +407,12 @@
#' @param target target return value
#' @param alpha alpha value for ETL/ES/CVaR
#' @param solver solver to use
+#' @param control list of solver control parameters
#' @author Ross Bennett
-etl_opt <- function(R, constraints, moments, target, alpha, solver="glpk"){
+etl_opt <- function(R, constraints, moments, target, alpha, solver="glpk", control=NULL){
stopifnot("package:ROI" %in% search() || require("ROI",quietly = TRUE))
- stopifnot("package:ROI.plugin.glpk" %in% search() || require("ROI.plugin.glpk",quietly = TRUE))
+ plugin <- paste0("ROI.plugin.", solver)
+ stopifnot(paste0("package:", plugin) %in% search() || require(plugin, quietly=TRUE, character.only=TRUE))
# Check for cleaned returns in moments
if(!is.null(moments$cleanR)) R <- moments$cleanR
@@ -456,7 +465,7 @@
opt.prob <- OP(objective=ROI_objective,
constraints=L_constraint(L=Amat, dir=dir.vec, rhs=rhs.vec),
bounds=bnds)
- roi.result <- try(ROI_solve(x=opt.prob, solver=solver), silent=TRUE)
+ roi.result <- try(ROI_solve(x=opt.prob, solver=solver, control=control), silent=TRUE)
if(inherits(x=roi.result, "try-error")) stop(paste("No solution found:", roi.result))
weights <- roi.result$solution[1:N]
@@ -498,10 +507,12 @@
#' @param target target return value
#' @param alpha alpha value for ETL/ES/CVaR
#' @param solver solver to use
+#' @param control list of solver control parameters
#' @author Ross Bennett
-etl_milp_opt <- function(R, constraints, moments, target, alpha, solver="glpk"){
+etl_milp_opt <- function(R, constraints, moments, target, alpha, solver="glpk", control=NULL){
stopifnot("package:ROI" %in% search() || require("ROI",quietly = TRUE))
- stopifnot("package:ROI.plugin.glpk" %in% search() || require("ROI.plugin.glpk",quietly = TRUE))
+ plugin <- paste0("ROI.plugin.", solver)
+ stopifnot(paste0("package:", plugin) %in% search() || require(plugin, quietly=TRUE, character.only=TRUE))
# Check for cleaned returns in moments
if(!is.null(moments$cleanR)) R <- moments$cleanR
@@ -605,7 +616,8 @@
opt.prob <- OP(objective=ROI_objective,
constraints=L_constraint(L=tmpAmat, dir=dir, rhs=rhs),
bounds=bnds, types=types)
- roi.result <- ROI_solve(x=opt.prob, solver=solver)
+ roi.result <- try(ROI_solve(x=opt.prob, solver=solver, control=control), silent=TRUE)
+ if(inherits(roi.result, "try-error")) stop(paste("No solution found:", roi.result))
# The Rglpk solvers status returns an an integer with status information
# about the solution returned: 0 if the optimal solution was found, a
@@ -654,12 +666,14 @@
#' @param target target return value
#' @param init_weights initial weights to compute turnover
#' @param solver solver to use
+#' @param control list of solver control parameters
#' @author Ross Bennett
-gmv_opt_toc <- function(R, constraints, moments, lambda, target, init_weights, solver="quadprog"){
+gmv_opt_toc <- function(R, constraints, moments, lambda, target, init_weights, solver="quadprog", control=NULL){
# function for minimum variance or max quadratic utility problems
stopifnot("package:corpcor" %in% search() || require("corpcor",quietly = TRUE))
stopifnot("package:ROI" %in% search() || require("ROI", quietly = TRUE))
- stopifnot("package:ROI.plugin.quadprog" %in% search() || require("ROI.plugin.quadprog", quietly = TRUE))
+ plugin <- paste0("ROI.plugin.", solver)
+ stopifnot(paste0("package:", plugin) %in% search() || require(plugin, quietly=TRUE, character.only=TRUE))
# Check for cleaned returns in moments
if(!is.null(moments$cleanR)) R <- moments$cleanR
@@ -766,8 +780,7 @@
opt.prob <- OP(objective=ROI_objective,
constraints=L_constraint(L=Amat, dir=dir, rhs=rhs))
- roi.result <- try(ROI_solve(x=opt.prob, solver=solver), silent=TRUE)
-
+ roi.result <- try(ROI_solve(x=opt.prob, solver=solver, control=control), silent=TRUE)
if(inherits(roi.result, "try-error")) stop(paste("No solution found:", roi.result))
wts <- roi.result$solution
@@ -810,13 +823,15 @@
#' @param target target return value
#' @param init_weights initial weights to compute turnover
#' @param solver solver to use
+#' @param control list of solver control parameters
#' @author Ross Bennett
-gmv_opt_ptc <- function(R, constraints, moments, lambda, target, init_weights, solver="quadprog"){
+gmv_opt_ptc <- function(R, constraints, moments, lambda, target, init_weights, solver="quadprog", control=NULL){
# function for minimum variance or max quadratic utility problems
# modifying ProportionalCostOpt function from MPO package
stopifnot("package:corpcor" %in% search() || require("corpcor", quietly = TRUE))
stopifnot("package:ROI" %in% search() || require("ROI", quietly = TRUE))
- stopifnot("package:ROI.plugin.quadprog" %in% search() || require("ROI.plugin.quadprog", quietly = TRUE))
+ plugin <- paste0("ROI.plugin.", solver)
+ stopifnot(paste0("package:", plugin) %in% search() || require(plugin, quietly=TRUE, character.only=TRUE))
# Check for cleaned returns in moments
if(!is.null(moments$cleanR)) R <- moments$cleanR
@@ -911,8 +926,7 @@
opt.prob <- OP(objective=ROI_objective,
constraints=L_constraint(L=Amat, dir=dir, rhs=rhs))
- roi.result <- try(ROI_solve(x=opt.prob, solver=solver), silent=TRUE)
-
+ roi.result <- try(ROI_solve(x=opt.prob, solver=solver, control=control), silent=TRUE)
if(inherits(roi.result, "try-error")) stop(paste("No solution found:", roi.result))
wts <- roi.result$solution
@@ -948,31 +962,31 @@
# This function uses optimize() to find the target return value that
# results in the maximum starr ratio (mean / ES).
# returns the target return value
-mean_etl_opt <- function(R, constraints, moments, alpha, solver){
+mean_etl_opt <- function(R, constraints, moments, alpha, solver, control){
# create a copy of the moments that can be modified
tmp_moments <- moments
# Find the maximum return
if(!is.null(constraints$max_pos)){
- max_ret <- maxret_milp_opt(R=R, constraints=constraints, moments=moments, target=NA, solver=solver)
+ max_ret <- maxret_milp_opt(R=R, constraints=constraints, moments=moments, target=NA, solver=solver, control=control)
} else {
- max_ret <- maxret_opt(R=R, moments=moments, constraints=constraints, target=NA, solver=solver)
+ max_ret <- maxret_opt(R=R, moments=moments, constraints=constraints, target=NA, solver=solver, control=control)
}
max_mean <- as.numeric(-max_ret$out)
# Find the minimum return
tmp_moments$mean <- -1 * moments$mean
if(!is.null(constraints$max_pos)){
- min_ret <- maxret_milp_opt(R=R, constraints=constraints, moments=tmp_moments, target=NA, solver=solver)
+ min_ret <- maxret_milp_opt(R=R, constraints=constraints, moments=tmp_moments, target=NA, solver=solver, control=control)
} else {
- min_ret <- maxret_opt(R=R, constraints=constraints, moments=tmp_moments, target=NA, solver=solver)
+ min_ret <- maxret_opt(R=R, constraints=constraints, moments=tmp_moments, target=NA, solver=solver, control=control)
}
min_mean <- as.numeric(min_ret$out)
# use optimize() to find the target return value that maximizes sharpe ratio
opt <- try(optimize(f=starr_obj_fun, R=R, constraints=constraints,
solver=solver, moments=moments, alpha=alpha,
- lower=min_mean, upper=max_mean,
+ lower=min_mean, upper=max_mean, control=control,
maximum=TRUE, tol=.Machine$double.eps),
silent=TRUE)
if(inherits(opt, "try-error")){
@@ -984,13 +998,15 @@
# Function to calculate the starr ratio.
# Used as the objective function for optimize()
-starr_obj_fun <- function(target_return, R, constraints, moments, alpha, solver){
+starr_obj_fun <- function(target_return, R, constraints, moments, alpha, solver, control){
if(!is.null(constraints$max_pos)){
opt <- etl_milp_opt(R=R, constraints=constraints, moments=moments,
- target=target_return, alpha=alpha, solver=solver)
+ target=target_return, alpha=alpha, solver=solver,
+ control=control)
} else {
opt <- etl_opt(R=R, constraints=constraints, moments=moments,
- target=target_return, alpha=alpha, solver=solver)
+ target=target_return, alpha=alpha, solver=solver,
+ control=control)
}
weights <- matrix(opt$weights, ncol=1)
opt_mean <- as.numeric(t(weights) %*% matrix(moments$mean, ncol=1))
@@ -1132,10 +1148,10 @@
# Function to calculate the sharpe ratio.
# Used as the objective function for optimize()
-sharpe_obj_fun <- function(target_return, R, constraints, moments, lambda_hhi=NULL, conc_groups=NULL, solver="quadprog"){
+sharpe_obj_fun <- function(target_return, R, constraints, moments, lambda_hhi=NULL, conc_groups=NULL, solver="quadprog", control=control){
opt <- gmv_opt(R=R, constraints=constraints, moments=moments, lambda=1,
- target=target_return, lambda_hhi=lambda_hhi,
- conc_groups=conc_groups, solver=solver)
+ target=target_return, lambda_hhi=lambda_hhi,
+ conc_groups=conc_groups, solver=solver, control=control)
weights <- opt$weights
opt_mean <- as.numeric(t(weights) %*% matrix(moments$mean, ncol=1))
opt_sd <- as.numeric(sqrt(t(weights) %*% moments$var %*% weights))
@@ -1146,25 +1162,25 @@
# This function uses optimize() to find the target return value that
# results in the maximum sharpe ratio (mean / sd).
# returns the target return value
-max_sr_opt <- function(R, constraints, moments, lambda_hhi, conc_groups, solver){
+max_sr_opt <- function(R, constraints, moments, lambda_hhi, conc_groups, solver, control){
# create a copy of the moments that can be modified
tmp_moments <- moments
# Find the maximum return
max_ret <- maxret_opt(R=R, moments=moments, constraints=constraints,
- target=NA, solver="glpk")
+ target=NA, solver=solver, control=control)
max_mean <- as.numeric(-max_ret$out)
# Find the minimum return
tmp_moments$mean <- -1 * moments$mean
min_ret <- maxret_opt(R=R, moments=tmp_moments, constraints=constraints,
- target=NA, solver="glpk")
+ target=NA, solver=solver, control=control)
min_mean <- as.numeric(min_ret$out)
# use optimize() to find the target return value that maximizes sharpe ratio
opt <- try(optimize(f=sharpe_obj_fun, R=R, constraints=constraints,
solver=solver, lambda_hhi=lambda_hhi,
- conc_groups=conc_groups, moments=moments,
+ conc_groups=conc_groups, moments=moments, control=control,
lower=min_mean, upper=max_mean,
maximum=TRUE, tol=.Machine$double.eps),
silent=TRUE)
Modified: pkg/PortfolioAnalytics/R/optimize.portfolio.R
===================================================================
--- pkg/PortfolioAnalytics/R/optimize.portfolio.R 2014-04-19 04:03:15 UTC (rev 3374)
+++ pkg/PortfolioAnalytics/R/optimize.portfolio.R 2014-04-20 16:38:03 UTC (rev 3375)
@@ -757,8 +757,11 @@
roi_solvers <- c("ROI", "quadprog", "glpk", "symphony", "ipop", "cplex")
if(optimize_method %in% roi_solvers){
+ # check for a control argument for list of solver control arguments
+ if(hasArg(control)) control=match.call(expand.dots=TRUE)$control else control=NULL
+
# This takes in a regular portfolio object and extracts the constraints and
- # objectives and converts them for input. to a closed form solver using
+ # objectives and converts them for input. to a closed form solver using
# ROI as an interface.
moments <- list(mean=rep(0, N))
alpha <- 0.05
@@ -840,14 +843,14 @@
constraints$ptc <- NULL
}
if(!is.null(constraints$turnover_target) & is.null(constraints$ptc)){
- qp_result <- gmv_opt_toc(R=R, constraints=constraints, moments=moments, lambda=lambda, target=target, init_weights=portfolio$assets, solver=solver)
+ qp_result <- gmv_opt_toc(R=R, constraints=constraints, moments=moments, lambda=lambda, target=target, init_weights=portfolio$assets, solver=solver, control=control)
weights <- qp_result$weights
# obj_vals <- constrained_objective(w=weights, R=R, portfolio, trace=TRUE, normalize=FALSE)$objective_measures
obj_vals <- qp_result$obj_vals
out <- list(weights=weights, objective_measures=obj_vals, opt_values=obj_vals, out=qp_result$out, call=call)
}
if(!is.null(constraints$ptc) & is.null(constraints$turnover_target)){
- qp_result <- gmv_opt_ptc(R=R, constraints=constraints, moments=moments, lambda=lambda, target=target, init_weights=portfolio$assets, solver=solver)
+ qp_result <- gmv_opt_ptc(R=R, constraints=constraints, moments=moments, lambda=lambda, target=target, init_weights=portfolio$assets, solver=solver, control=control)
weights <- qp_result$weights
# obj_vals <- constrained_objective(w=weights, R=R, portfolio, trace=TRUE, normalize=FALSE)$objective_measures
obj_vals <- qp_result$obj_vals
@@ -857,12 +860,12 @@
# if(hasArg(ef)) ef=match.call(expand.dots=TRUE)$ef else ef=FALSE
if(hasArg(maxSR)) maxSR=match.call(expand.dots=TRUE)$maxSR else maxSR=FALSE
if(maxSR){
- target <- max_sr_opt(R=R, constraints=constraints, moments=moments, lambda_hhi=lambda_hhi, conc_groups=conc_groups, solver=solver)
+ target <- max_sr_opt(R=R, constraints=constraints, moments=moments, lambda_hhi=lambda_hhi, conc_groups=conc_groups, solver=solver, control=control)
# need to set moments$mean=0 here because quadratic utility and target return is sensitive to returning no solution
tmp_moments_mean <- moments$mean
moments$mean <- rep(0, length(moments$mean))
}
- roi_result <- gmv_opt(R=R, constraints=constraints, moments=moments, lambda=lambda, target=target, lambda_hhi=lambda_hhi, conc_groups=conc_groups, solver=solver)
+ roi_result <- gmv_opt(R=R, constraints=constraints, moments=moments, lambda=lambda, target=target, lambda_hhi=lambda_hhi, conc_groups=conc_groups, solver=solver, control=control)
weights <- roi_result$weights
# obj_vals <- constrained_objective(w=weights, R=R, portfolio, trace=TRUE, normalize=FALSE)$objective_measures
obj_vals <- roi_result$obj_vals
@@ -887,14 +890,14 @@
# Maximize return if the only objective specified is mean
if(!is.null(constraints$max_pos) | !is.null(constraints$leverage)) {
# This is an MILP problem if max_pos is specified as a constraint
- roi_result <- maxret_milp_opt(R=R, constraints=constraints, moments=moments, target=target, solver=solver)
+ roi_result <- maxret_milp_opt(R=R, constraints=constraints, moments=moments, target=target, solver=solver, control=control)
weights <- roi_result$weights
# obj_vals <- constrained_objective(w=weights, R=R, portfolio, trace=TRUE, normalize=FALSE)$objective_measures
obj_vals <- roi_result$obj_vals
out <- list(weights=weights, objective_measures=obj_vals, opt_values=obj_vals, out=roi_result$out, call=call)
} else {
# Maximize return LP problem
- roi_result <- maxret_opt(R=R, constraints=constraints, moments=moments, target=target, solver=solver)
+ roi_result <- maxret_opt(R=R, constraints=constraints, moments=moments, target=target, solver=solver, control=control)
weights <- roi_result$weights
# obj_vals <- constrained_objective(w=weights, R=R, portfolio, trace=TRUE, normalize=FALSE)$objective_measures
obj_vals <- roi_result$obj_vals
@@ -918,12 +921,12 @@
# Minimize sample ETL/ES/CVaR if CVaR, ETL, or ES is specified as an objective
if(length(moments) == 2 & all(moments$mean != 0) & ef==FALSE & maxSTARR){
# This is called by meanetl.efficient.frontier and we do not want that for efficient frontiers, need to have ef==FALSE
- target <- mean_etl_opt(R=R, constraints=constraints, moments=moments, alpha=alpha, solver=solver)
+ target <- mean_etl_opt(R=R, constraints=constraints, moments=moments, alpha=alpha, solver=solver, control=control)
meanetl <- TRUE
}
if(!is.null(constraints$max_pos)) {
# This is an MILP problem if max_pos is specified as a constraint
- roi_result <- etl_milp_opt(R=R, constraints=constraints, moments=moments, target=target, alpha=alpha, solver=solver)
+ roi_result <- etl_milp_opt(R=R, constraints=constraints, moments=moments, target=target, alpha=alpha, solver=solver, control=control)
weights <- roi_result$weights
# obj_vals <- constrained_objective(w=weights, R=R, portfolio, trace=TRUE, normalize=FALSE)$objective_measures
# obj_vals <- roi_result$obj_vals
@@ -934,7 +937,7 @@
out <- list(weights=weights, objective_measures=obj_vals, opt_values=obj_vals, out=roi_result$out, call=call)
} else {
# Minimize sample ETL/ES/CVaR LP Problem
- roi_result <- etl_opt(R=R, constraints=constraints, moments=moments, target=target, alpha=alpha, solver=solver)
+ roi_result <- etl_opt(R=R, constraints=constraints, moments=moments, target=target, alpha=alpha, solver=solver, control=control)
weights <- roi_result$weights
# obj_vals <- constrained_objective(w=weights, R=R, portfolio, trace=TRUE, normalize=FALSE)$objective_measures
# obj_vals <- roi_result$obj_vals
Modified: pkg/PortfolioAnalytics/man/etl_milp_opt.Rd
===================================================================
--- pkg/PortfolioAnalytics/man/etl_milp_opt.Rd 2014-04-19 04:03:15 UTC (rev 3374)
+++ pkg/PortfolioAnalytics/man/etl_milp_opt.Rd 2014-04-20 16:38:03 UTC (rev 3375)
@@ -3,7 +3,7 @@
\title{Minimum ETL MILP Optimization}
\usage{
etl_milp_opt(R, constraints, moments, target, alpha,
- solver = "glpk")
+ solver = "glpk", control = NULL)
}
\arguments{
\item{R}{xts object of asset returns}
@@ -19,6 +19,8 @@
\item{alpha}{alpha value for ETL/ES/CVaR}
\item{solver}{solver to use}
+
+ \item{control}{list of solver control parameters}
}
\description{
This function is called by optimize.portfolio to solve
Modified: pkg/PortfolioAnalytics/man/etl_opt.Rd
===================================================================
--- pkg/PortfolioAnalytics/man/etl_opt.Rd 2014-04-19 04:03:15 UTC (rev 3374)
+++ pkg/PortfolioAnalytics/man/etl_opt.Rd 2014-04-20 16:38:03 UTC (rev 3375)
@@ -3,7 +3,7 @@
\title{Minimum ETL LP Optimization}
\usage{
etl_opt(R, constraints, moments, target, alpha,
- solver = "glpk")
+ solver = "glpk", control = NULL)
}
\arguments{
\item{R}{xts object of asset returns}
@@ -19,6 +19,8 @@
\item{alpha}{alpha value for ETL/ES/CVaR}
\item{solver}{solver to use}
+
+ \item{control}{list of solver control parameters}
}
\description{
This function is called by optimize.portfolio to solve
Modified: pkg/PortfolioAnalytics/man/gmv_opt.Rd
===================================================================
--- pkg/PortfolioAnalytics/man/gmv_opt.Rd 2014-04-19 04:03:15 UTC (rev 3374)
+++ pkg/PortfolioAnalytics/man/gmv_opt.Rd 2014-04-20 16:38:03 UTC (rev 3375)
@@ -3,7 +3,8 @@
\title{GMV/QU QP Optimization}
\usage{
gmv_opt(R, constraints, moments, lambda, target,
- lambda_hhi, conc_groups, solver = "quadprog")
+ lambda_hhi, conc_groups, solver = "quadprog",
+ control = NULL)
}
\arguments{
\item{R}{xts object of asset returns}
@@ -24,6 +25,8 @@
of the assets.}
\item{solver}{solver to use}
+
+ \item{control}{list of solver control parameters}
}
\description{
This function is called by optimize.portfolio to solve
Modified: pkg/PortfolioAnalytics/man/gmv_opt_ptc.Rd
===================================================================
--- pkg/PortfolioAnalytics/man/gmv_opt_ptc.Rd 2014-04-19 04:03:15 UTC (rev 3374)
+++ pkg/PortfolioAnalytics/man/gmv_opt_ptc.Rd 2014-04-20 16:38:03 UTC (rev 3375)
@@ -3,7 +3,7 @@
\title{GMV/QU QP Optimization with Proportional Transaction Cost Constraint}
\usage{
gmv_opt_ptc(R, constraints, moments, lambda, target,
- init_weights, solver = "quadprog")
+ init_weights, solver = "quadprog", control = NULL)
}
\arguments{
\item{R}{xts object of asset returns}
@@ -21,6 +21,8 @@
\item{init_weights}{initial weights to compute turnover}
\item{solver}{solver to use}
+
+ \item{control}{list of solver control parameters}
}
\description{
This function is called by optimize.portfolio to solve
Modified: pkg/PortfolioAnalytics/man/gmv_opt_toc.Rd
===================================================================
--- pkg/PortfolioAnalytics/man/gmv_opt_toc.Rd 2014-04-19 04:03:15 UTC (rev 3374)
+++ pkg/PortfolioAnalytics/man/gmv_opt_toc.Rd 2014-04-20 16:38:03 UTC (rev 3375)
@@ -3,7 +3,7 @@
\title{GMV/QU QP Optimization with Turnover Constraint}
\usage{
gmv_opt_toc(R, constraints, moments, lambda, target,
- init_weights, solver = "quadprog")
+ init_weights, solver = "quadprog", control = NULL)
}
\arguments{
\item{R}{xts object of asset returns}
@@ -21,6 +21,8 @@
\item{init_weights}{initial weights to compute turnover}
\item{solver}{solver to use}
+
+ \item{control}{list of solver control parameters}
}
\description{
This function is called by optimize.portfolio to solve
Modified: pkg/PortfolioAnalytics/man/maxret_milp_opt.Rd
===================================================================
--- pkg/PortfolioAnalytics/man/maxret_milp_opt.Rd 2014-04-19 04:03:15 UTC (rev 3374)
+++ pkg/PortfolioAnalytics/man/maxret_milp_opt.Rd 2014-04-20 16:38:03 UTC (rev 3375)
@@ -3,7 +3,7 @@
\title{Maximum Return MILP Optimization}
\usage{
maxret_milp_opt(R, constraints, moments, target,
- solver = "glpk")
+ solver = "glpk", control = NULL)
}
\arguments{
\item{R}{xts object of asset returns}
@@ -17,6 +17,8 @@
\item{target}{target return value}
\item{solver}{solver to use}
+
+ \item{control}{list of solver control parameters}
}
\description{
This function is called by optimize.portfolio to solve
Modified: pkg/PortfolioAnalytics/man/maxret_opt.Rd
===================================================================
--- pkg/PortfolioAnalytics/man/maxret_opt.Rd 2014-04-19 04:03:15 UTC (rev 3374)
+++ pkg/PortfolioAnalytics/man/maxret_opt.Rd 2014-04-20 16:38:03 UTC (rev 3375)
@@ -3,7 +3,7 @@
\title{Maximum Return LP Optimization}
\usage{
maxret_opt(R, moments, constraints, target,
- solver = "glpk")
+ solver = "glpk", control = NULL)
}
\arguments{
\item{R}{xts object of asset returns}
@@ -17,6 +17,8 @@
\item{target}{target return value}
\item{solver}{solver to use}
+
+ \item{control}{list of solver control parameters}
}
\description{
This function is called by optimize.portfolio to solve
From noreply at r-forge.r-project.org Mon Apr 21 05:48:01 2014
From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org)
Date: Mon, 21 Apr 2014 05:48:01 +0200 (CEST)
Subject: [Returnanalytics-commits] r3376 - pkg/PortfolioAnalytics/R
Message-ID: <20140421034801.E7804186B46@r-forge.r-project.org>
Author: rossbennett34
Date: 2014-04-21 05:47:59 +0200 (Mon, 21 Apr 2014)
New Revision: 3376
Modified:
pkg/PortfolioAnalytics/R/extract.efficient.frontier.R
Log:
Adding check for hhi objective in mean-var efficient frontier
Modified: pkg/PortfolioAnalytics/R/extract.efficient.frontier.R
===================================================================
--- pkg/PortfolioAnalytics/R/extract.efficient.frontier.R 2014-04-20 16:38:03 UTC (rev 3375)
+++ pkg/PortfolioAnalytics/R/extract.efficient.frontier.R 2014-04-21 03:47:59 UTC (rev 3376)
@@ -101,15 +101,24 @@
var_idx <- which(unlist(lapply(portfolio$objectives, function(x) x$name)) %in% c("var", "StdDev", "sd"))
if(length(var_idx) >= 1){
# the portfolio object has a var, StdDev, or sd objective
- var_obj <- portfolio$objectives[[var_idx]]
+ var_obj <- portfolio$objectives[[var_idx[1]]]
} else {
var_obj <- portfolio_risk_objective(name="var")
}
+ hhi_idx <- which(unlist(lapply(portfolio$objectives, function(x) x$name)) == "HHI")
+ if(length(hhi_idx) >= 1){
+ # the portfolio object has an HHI objective
+ hhi_obj <- portfolio$objectives[[hhi_idx[1]]]
+ } else {
+ hhi_obj <- NULL
+ }
+
# Clear out the objectives in portfolio and add them here to simplify checks
# and so we can control the optimization along the efficient frontier.
portfolio$objectives <- list()
portfolio$objectives[[1]] <- var_obj
+ portfolio$objectives[[2]] <- hhi_obj
portfolio <- add.objective(portfolio=portfolio, type="return", name="mean")
# If the user has passed in a portfolio object with return_constraint, we need to disable it
@@ -123,11 +132,14 @@
var_idx <- which(unlist(lapply(portfolio$objectives, function(x) x$name)) %in% c("var", "StdDev", "sd"))
# get the index number of the mean objective
mean_idx <- which(unlist(lapply(portfolio$objectives, function(x) x$name)) == "mean")
+ # get the index number of the hhi objective
+ hhi_idx <- which(unlist(lapply(portfolio$objectives, function(x) x$name)) == "HHI")
##### get the maximum return #####
- # Disable the risk objective
+ # Disable the risk objective and hhi objective if applicable
portfolio$objectives[[var_idx]]$enabled <- FALSE
+ if(length(hhi_idx) >= 1) portfolio$objectives[[hhi_idx]]$enabled <- FALSE
# run the optimization to get the maximum return
tmp <- optimize.portfolio(R=R, portfolio=portfolio, optimize_method="ROI", ...=...)
@@ -139,8 +151,9 @@
# Disable the return objective
portfolio$objectives[[mean_idx]]$enabled <- FALSE
- # Enable the risk objective
+ # Enable the risk objective and hhi objective if applicable
portfolio$objectives[[var_idx]]$enabled <- TRUE
+ if(length(hhi_idx) >= 1) portfolio$objectives[[hhi_idx]]$enabled <- TRUE
# Run the optimization to get the global minimum variance portfolio with the
# given constraints.
@@ -208,7 +221,7 @@
etl_idx <- which(unlist(lapply(portfolio$objectives, function(x) x$name)) %in% c("ETL", "ES", "CVaR"))
if(length(etl_idx) >= 1){
# the portfolio object has a ETL, ES, CVaR objective
- etl_obj <- portfolio$objectives[[etl_idx]]
+ etl_obj <- portfolio$objectives[[etl_idx[1]]]
} else {
etl_obj <- portfolio_risk_objective(name="ES", arguments=list(p=0.95))
}
From noreply at r-forge.r-project.org Sun Apr 27 04:53:28 2014
From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org)
Date: Sun, 27 Apr 2014 04:53:28 +0200 (CEST)
Subject: [Returnanalytics-commits] r3377 - in
pkg/PortfolioAnalytics/sandbox/RFinance2014: . R
Message-ID: <20140427025328.DF851186FE5@r-forge.r-project.org>
Author: rossbennett34
Date: 2014-04-27 04:53:24 +0200 (Sun, 27 Apr 2014)
New Revision: 3377
Added:
pkg/PortfolioAnalytics/sandbox/RFinance2014/R/charting.R
Modified:
pkg/PortfolioAnalytics/sandbox/RFinance2014/makefile
pkg/PortfolioAnalytics/sandbox/RFinance2014/optimization_analysis.R
pkg/PortfolioAnalytics/sandbox/RFinance2014/optimize.R
pkg/PortfolioAnalytics/sandbox/RFinance2014/presentation.Rmd
pkg/PortfolioAnalytics/sandbox/RFinance2014/presentation.md
pkg/PortfolioAnalytics/sandbox/RFinance2014/slides.pdf
pkg/PortfolioAnalytics/sandbox/RFinance2014/slidy_presentation.html
Log:
Updating presentation
Added: pkg/PortfolioAnalytics/sandbox/RFinance2014/R/charting.R
===================================================================
--- pkg/PortfolioAnalytics/sandbox/RFinance2014/R/charting.R (rev 0)
+++ pkg/PortfolioAnalytics/sandbox/RFinance2014/R/charting.R 2014-04-27 02:53:24 UTC (rev 3377)
@@ -0,0 +1,99 @@
+nvd3WeightsPlot <- function(object,
+ type=c("stackedAreaChart", "multiBarChart")
+ ){
+ type <- match.arg(type)
+
+ # extract the weights and turn into a data.frame
+ weights <- extractWeights(object)
+ weights.df <- reshape2::melt(
+ data.frame(date=format(index(weights)), weights),
+ id.vars = 1,
+ variable.name = "stock",
+ value.name = "weight"
+ )
+ weights.df$date <- as.Date(weights.df$date)
+
+ # plot
+ n1 <- rCharts::nPlot(
+ weight ~ date,
+ group = "stock",
+ data = weights.df,
+ type = type
+ )
+ n1$xAxis(
+ tickFormat = "#!function(d){
+ return d3.time.format('%b %Y')(new Date(d * 24 * 60 * 60 * 1000))
+ }!#"
+ )
+ n1$yAxis(
+ tickFormat = "#!function(d){
+ return d3.format('0.2%')(d)
+ }!#"
+ )
+ return(n1)
+}
+
+nvd3RiskPlot <- function(object,
+ type=c("stackedAreaChart", "multiBarChart")
+ ){
+ type <- match.arg(type)
+
+ # extract the risk budget pct_contrib and turn into a data.frame
+ tmp <- extractObjectiveMeasures(object)
+ rb <- tmp[,grep("pct_contrib", colnames(tmp))]
+ colnames(rb) <- gsub("^.*\\.", "", colnames(rb))
+ rb.df <- reshape2::melt(
+ data.frame(date=as.Date(format(index(rb))), rb),
+ id.vars = 1,
+ variable.name = "fund",
+ value.name = "risk"
+ )
+
+ # plot
+ n1 <- rCharts::nPlot(
+ risk ~ date,
+ group = "fund",
+ data = rb.df,
+ type = type
+ )
+ n1$xAxis(
+ tickFormat = "#!function(d){
+ return d3.time.format('%b %Y')(new Date(d * 24 * 60 * 60 * 1000))
+ }!#"
+ )
+ n1$yAxis(
+ tickFormat = "#!function(d){
+ return d3.format('0.2%')(d)
+ }!#"
+ )
+ return(n1)
+}
+
+# require(rCharts)
+# weights <- extractWeights(opt.minVarSample)
+# weights.df <- reshape2::melt(
+# data.frame(
+# date=format(index(weights)),
+# weights
+# ),
+# id.vars = 1,
+# variable.name = "stock",
+# value.name = "weight"
+# )
+#
+# d1 <- dPlot(
+# weight ~ date,
+# groups = "stock",
+# data = weights.df,
+# type = "bubble" #area, bar, or bubble
+# )
+# d1$xAxis(
+# type = "addTimeAxis",
+# inputFormat = "%Y-%m-%d",
+# outputFormat = "%b %Y"
+# )
+# d1$yAxis(
+# outputFormat = "0.2%",
+# orderBy = "weight"
+# )
+# d1
\ No newline at end of file
Modified: pkg/PortfolioAnalytics/sandbox/RFinance2014/makefile
===================================================================
--- pkg/PortfolioAnalytics/sandbox/RFinance2014/makefile 2014-04-21 03:47:59 UTC (rev 3376)
+++ pkg/PortfolioAnalytics/sandbox/RFinance2014/makefile 2014-04-27 02:53:24 UTC (rev 3377)
@@ -13,8 +13,12 @@
# Generate slidy presentation from markdown file
slidy_presentation.html: $(RFILES) $(OUT_FILES) presentation.md
- pandoc -t slidy -s presentation.md -o slidy_presentation.html
+ pandoc -t slidy -s --mathjax presentation.md -o slidy_presentation.html
+# Generate slidy presentation from markdown file
+slides.pdf: $(RFILES) $(OUT_FILES) presentation.md
+ pandoc -t -S beamer ?-slide-level 2 presentation.md -o slides.pdf
+
# Generate markdown file from R markdown file
presentation.md: presentation.Rmd
Rscript -e "library(knitr); knit('presentation.Rmd')"
@@ -38,6 +42,9 @@
lwShrink.Rout: R/lwShrink.R
R CMD BATCH --vanilla R/lwShrink.R
+charting.Rout: R/charting.R
+ R CMD BATCH --vanilla R/charting.R
+
# Use Rscript to run the necessary R files as an alternative to R CMD BATCH
runR:
Rscript data_prep.R
@@ -52,4 +59,5 @@
rm -f optimization_results/*.rda
rm -f *.md
rm -f *.html
+ rm -f cache/*
\ No newline at end of file
Modified: pkg/PortfolioAnalytics/sandbox/RFinance2014/optimization_analysis.R
===================================================================
--- pkg/PortfolioAnalytics/sandbox/RFinance2014/optimization_analysis.R 2014-04-21 03:47:59 UTC (rev 3376)
+++ pkg/PortfolioAnalytics/sandbox/RFinance2014/optimization_analysis.R 2014-04-27 02:53:24 UTC (rev 3377)
@@ -1,6 +1,8 @@
library(PortfolioAnalytics)
library(methods)
+source("R/charting.R")
+
# Set the directory where the optimization results are saved
results.dir <- "optimization_results"
figures.dir <- "optimization_figures"
@@ -15,10 +17,17 @@
chart.Weights(opt.minVarSample, main="minVarSample Weights", legend.loc=NULL)
dev.off()
+w1 <- nvd3WeightsPlot(opt.minVarSample)
+save(w1, file=paste(figures.dir, "w1.rda", sep="/"))
+
+
png(paste(figures.dir, "weights_minVarLW.png", sep="/"))
chart.Weights(opt.minVarLW, main="minVarLW Weights", legend.loc=NULL)
dev.off()
+w2 <- nvd3WeightsPlot(opt.minVarLW)
+save(w2, file=paste(figures.dir, "w2.rda", sep="/"))
+
# Compute the returns and chart the performance summary
ret.minVarSample <- summary(opt.minVarSample)$portfolio_returns
ret.minVarRobust <- summary(opt.minVarLW)$portfolio_returns
@@ -65,8 +74,9 @@
# plot the feasible space
par(mar=c(7,4,4,1)+0.1)
plot(xtract.ES, xtract.mean, col="gray",
+ main="Minimum ES Portfolios",
xlab="ES", ylab="Mean",
- ylim=c(0.005, 0.008),
+ ylim=c(0.005, 0.007),
xlim=c(0.015, 0.085))
# min ES
@@ -92,7 +102,7 @@
text(x=opt.minES[[3]]$objective_measures$ES$MES,
y=opt.minES[[3]]$objective_measures$mean,
labels="Min ES EqRB", pos=4, col="darkgreen", cex=0.8)
-# par(mar=c(7,4,4,1)+0.1)
+par(mar=c(5,4,4,1)+0.1)
dev.off()
# Chart the risk contribution
@@ -146,6 +156,13 @@
charts.PerformanceSummary(ret.bt.opt)
dev.off()
+###
+# interactive plot of risk budgets through time using nvd3
+# nvd3RiskPlot(bt.opt.minES[[1]])
+# nvd3RiskPlot(bt.opt.minES[[2]])
+# nvd3RiskPlot(bt.opt.minES[[3]])
+###
+
##### Example 4 #####
load(file=paste(results.dir, "opt.crra.rda", sep="/"))
load(file=paste(results.dir, "bt.opt.crra.rda", sep="/"))
Modified: pkg/PortfolioAnalytics/sandbox/RFinance2014/optimize.R
===================================================================
--- pkg/PortfolioAnalytics/sandbox/RFinance2014/optimize.R 2014-04-21 03:47:59 UTC (rev 3376)
+++ pkg/PortfolioAnalytics/sandbox/RFinance2014/optimize.R 2014-04-27 02:53:24 UTC (rev 3377)
@@ -62,8 +62,8 @@
# Add constraints
# weights sum to 1
portf.minvar <- add.constraint(portf.init, type="full_investment")
-# box constraints such that no stock has weight less than 1% or greater than 20%
-portf.minvar <- add.constraint(portf.minvar, type="box", min=0.01, max=0.2)
+# box constraints
+portf.minvar <- add.constraint(portf.minvar, type="box", min=0.01, max=0.45)
# Add objective
# objective to minimize portfolio variance
@@ -368,7 +368,15 @@
x.assets <- StdDev(R)
y.assets <- colMeans(R)
-
+ ###
+ # create an interactive plot using rCharts and nvd3 scatterChart
+ # tmp1 <- data.frame(name="sample", mean=rp1_mean, sd=rp1_StdDev)
+ # tmp2 <- data.frame(name="simplex", mean=rp2_mean, sd=rp2_StdDev)
+ # tmp3 <- data.frame(name="grid", mean=rp3_mean, sd=rp3_StdDev)
+ # tmp <- rbind(tmp1, tmp2, tmp3)
+ # n1 <- nPlot(mean ~ sd, group="name", data=tmp, type="scatterChart")
+ # n1
+ ###
x.lower <- min(x.assets) * 0.9
x.upper <- max(x.assets) * 1.1
y.lower <- min(y.assets) * 0.9
Modified: pkg/PortfolioAnalytics/sandbox/RFinance2014/presentation.Rmd
===================================================================
--- pkg/PortfolioAnalytics/sandbox/RFinance2014/presentation.Rmd 2014-04-21 03:47:59 UTC (rev 3376)
+++ pkg/PortfolioAnalytics/sandbox/RFinance2014/presentation.Rmd 2014-04-27 02:53:24 UTC (rev 3377)
@@ -1,14 +1,32 @@
-% R/Finance 2014: Complex Portfolio Optimization with PortfolioAnalytics
-% Ross Bennett
-% May 16, 2014
+---
+title : Complex Portfolio Optimization with PortfolioAnalytics
+subtitle : R/Finance 2014
+author : Ross Bennett
+date : May 16, 2014
+---
-# Overview
+```{r, echo=FALSE, message=FALSE}
+library(PortfolioAnalytics)
+```
+
+
+## Overview
* Discuss Portfolio Optimization
* Introduce PortfolioAnalytics
* Demonstrate PortfolioAnalytics with Examples
-# Portfolio Optimization
+
+---
+
## Modern Portfolio Theory
"Modern" Portfolio Theory (MPT) was introduced by Harry Markowitz in 1952.
@@ -22,9 +40,11 @@
How do we define risk? What about more complex objectives?
+---
+
## Portfolio Optimization Objectives
* Minimize Risk
* Volatility
@@ -43,10 +63,9 @@
The challenge here is knowing what solver to use and the capabilities/limits of the chosen solver. Talk about pros/cons of closed-form solvers vs. global solvers and what objectives can be solved.
-->
-# PortfolioAnalytics
+---
-## Overview
-
+## PortfolioAnalytics Overview
PortfolioAnalytics is an R package designed to provide numerical solutions and visualizations for portfolio optimization problems with complex constraints and objectives.
* Support for multiple constraint and objective types
@@ -69,9 +88,9 @@
- Periodic rebalancing and analyzing out of sample performance will help refine objectives and constraints
-->
+---
## Support Multiple Solvers
-
Linear and Quadratic Programming Solvers
* R Optimization Infrastructure (ROI)
@@ -90,6 +109,8 @@
Brief explanation of each solver and what optimization problems (constraints and objectives) are supported
-->
+---
+
## Random Portfolios
PortfolioAnalytics has three methods to generate random portfolios.
@@ -107,18 +128,25 @@
The grid method to generate random portfolios is based on the gridSearch function in NMOF package. The grid search method only satisfies the min and max box constraints. The min_sum and max_sum leverage constraint will likely be violated and the weights in the random portfolios should be normalized. Normalization may cause the box constraints to be violated and will be penalized in constrained_objective.
-->
+---
+
## Comparison of Random Portfolio Methods
![](optimization_figures/rp_plot.png)
+
+
+---
+
## Random Portfolios: Simplex Method
![](optimization_figures/fev_plot.png)
+---
## Workflow
-TODO: Add a nice graphic here (Guy might have one)
+![](misc_figures/workflow.png)
-Specify a Portfolio --> Add Constraints --> Add Objectives --> Run Optimization --> Analyze Results
-
+---
-# Example 1
+## Workflow: Specify Portfolio
+```{r}
+args(portfolio.spec)
+```
-## Data Setup
+---
+
+## Workflow: Add Constraints
+```{r}
+args(add.constraint)
+```
+
+Supported Constraint Types
+
+* Sum of Weights
+* Box
+* Group
+* Turnover
+* Diversification
+* Position Limit
+* Return
+* Factor Exposure
+
+---
+
+## Workflow: Add Objectives
+```{r}
+args(add.objective)
+```
+
+Supported Objective types
+
+* Return
+* Risk
+* Risk Budget
+* Weight Concentration
+
+---
+
+## Workflow: Run Optimization
+```{r}
+args(optimize.portfolio)
+args(optimize.portfolio.rebalancing)
+```
+
+Supported Optimization Methods
+
+* ROI
+* random
+* DEoptim
+* pso
+* GenSA
+
+---
+
+## Workflow: Analyze Results
+
+Charting Functions
+
+* plot
+* chart.Concentration
+* chart.EfficientFrontier
+* chart.RiskBudget
+* chart.RiskReward
+* chart.Weights
+
+Extract Functions
+
+* extractObjectiveMeasures
+* extractStats
+* extractWeights
+
+
+
+---
+
+## Example 1: Data Setup
Here we will look at portfolio optimization in the context of stocks.
* Selection of large cap, mid cap, and small cap stocks from CRSP data
@@ -145,16 +250,26 @@
smallcap_weekly[,1:5])
```
+---
+
## Distribution of Monthly Returns
![](data_figures/equity_box.png)
+---
+
## Minimum Variance Portfolio
-Consider a portfolio of stocks. Our objective to minimize portfolio variance subect to full investment and box constraints. We will use out of sample backtesting to compare the sample covariance matrix estimate and a Ledoit-Wolf shinkage estimate.
+Here we consider a portfolio of stocks. Our objective is to minimize portfolio variance subect to full investment and box constraints. We will use out of sample backtesting to compare the sample covariance matrix estimate and a Ledoit-Wolf shinkage estimate.
+$$
+\min_{w} w^{T} \Sigma w
+$$
+
+---
+
## Specify Portfolio
```{r,eval=FALSE}
# Specify an initial portfolio
@@ -165,8 +280,8 @@
portf.minvar <- add.constraint(portf.init, type="full_investment")
# Add box constraint such that no asset can have a weight of greater than
-# 20% or less than 1%
-portf.minvar <- add.constraint(portf.minvar, type="box", min=0.01, max=0.2)
+# 45% or less than 1%
+portf.minvar <- add.constraint(portf.minvar, type="box", min=0.01, max=0.45)
# Add objective to minimize portfolio variance
portf.minvar <- add.objective(portf.minvar, type="risk", name="var")
@@ -176,6 +291,8 @@
Talk a little about adding constraints and objectives
-->
+---
+
## Ledoit-Wolf Shrinkage Estimate
The default function for `momentFUN` is `set.portfolio.moments`. We need to write our own function to estimate the covariance matrix.
```{r, eval=FALSE}
@@ -187,39 +304,32 @@
}
```
-## Backtesting Parameters
-```{r, eval=FALSE}
-# Set rebalancing frequency
-rebal.freq <- "quarters"
+---
-# Training Period
-training <- 400
-
-# Trailing Period
-trailing <- 250
-```
-
-
## Run Optimization
```{r, eval=FALSE, tidy=FALSE}
# Backtest using sample covariance matrix estimate
opt.minVarSample <- optimize.portfolio.rebalancing(equity.data, portf.minvar,
optimize_method="ROI",
- rebalance_on=rebal.freq,
- training_period=training,
- trailing_periods=trailing)
+ rebalance_on="quarters",
+ training_period=400,
+ trailing_periods=250)
# Backtest using Ledoit-Wolf shrinkage covariance matrix estimate
opt.minVarLW <- optimize.portfolio.rebalancing(equity.data, portf.minvar,
optimize_method="ROI",
momentFUN=lw.sigma,
- rebalance_on=rebal.freq,
- training_period=training,
- trailing_periods=trailing)
+ rebalance_on="quarters",
+ training_period=400,
+ trailing_periods=250)
```
+
+
+---
+
## Chart Weights Through Time
```{r, eval=FALSE}
chart.Weights(opt.minVarSample, main="minVarSample Weights", legend.loc=NULL)
@@ -228,6 +338,8 @@
![](optimization_figures/weights_minVarSample.png)
![](optimization_figures/weights_minVarLW.png)
+---
+
## Returns
Compute the portfolio rebalancing returns and chart the performance.
```{r, eval=FALSE}
@@ -237,20 +349,20 @@
colnames(ret.minVar) <- c("Sample", "LW")
charts.PerformanceSummary(ret.minVar)
```
-
-## Performance Summary
![](optimization_figures/ret_minVar.png)
-# Example 2
+---
-## Market Neutral Portfolio
+## Example 2: Market Neutral Portfolio
Here we consider a portfolio of stocks. Our objective is to maximize portfolio return with a target of 0.0015 and minimize portfolio StdDev with a target of 0.02 subject to dollar neutral, beta, box, and position limit constraints. We will use the same data considered in Example 1.
-## Specify Portfolio: Contraints
+---
+
+## Specify Portfolio: Constraints
```{r, eval=FALSE, tidy=FALSE}
portf.init <- portfolio.spec(stocks)
@@ -277,6 +389,8 @@
explain the constraints
-->
+---
+
## Specify Portfolio: Objectives
```{r,eval=FALSE, tidy=FALSE}
# Add objective to maximize portfolio return with a target of 0.0015
@@ -292,6 +406,8 @@
explain the objectives, specifically the target
-->
+---
+
## Run Optimization
```{r, eval=FALSE, tidy=FALSE}
# Generate random portfolios
@@ -307,16 +423,17 @@
generate a set of random portfolios and then pass directly to optimize.portfolio. Could just specify optimize_method = "random" and will automatically generate for you.
-->
+---
+
## Plot Results
```{r, eval=FALSE, tidy=FALSE}
plot(opt.dn, main="Dollar Neutral Portfolio", risk.col="StdDev", neighbors=10)
```
![](optimization_figures/opt_dn.png)
+---
-# Example 3
-
-## Data Setup
+## Example 3: Data Setup
Here we will look at portfolio optimization in the context of portfolio of hedge funds.
* EDHEC-Risk Alternative Indexes
@@ -328,7 +445,6 @@
* Emerging Markets (EM)
* Global Macro (GM)
-## Data
```{r, eval=FALSE, tidy=FALSE}
R <- edhec[,c("Convertible.Arbitrage", "Equity.Market.Neutral",
"Fixed.Income.Arbitrage",
@@ -337,14 +453,18 @@
colnames(R) <- c("CA", "EMN", "FIA", "CTAG", "EM", "GM")
```
+---
+
## Monthly Returns
![](data_figures/relative_barvar.png)
![](data_figures/directional_barvar.png)
+---
## Distribution of Monthly Returns
![](data_figures/edhec_box.png)
+---
## Minimum Expected Shortfall
Consider an allocation to hedge funds using the EDHEC-Risk Alternative Index as a proxy. This will be an extended example starting with an objective to minimize modified expected shortfall, then add risk budget percent contribution limit, and finally add equal risk contribution limit.
@@ -353,12 +473,16 @@
* Minimize Expected Shortfall with Risk Budget Limit
* Minimize Expected Shortfall with Equal Risk Contribution
-Add risk budget objective to minimize concentration of percentage component contribution to risk. Concentration is defined as the Herfindahl-Hirschman Index (HHI). $\sum_i x_i^2$
+Add risk budget objective to minimize concentration of percentage component contribution to risk. Concentration is defined as the Herfindahl Hirschman Index (HHI).
+$$ \sum_{i=1}^n x_i^2 $$
+
+---
+
## Specify Initial Portfolio
```{r, eval=FALSE, tidy=FALSE}
# Specify an initial portfolio
@@ -384,6 +508,8 @@
basic comments about setting up an initial portfolio
-->
+---
+
## Add Objectives
```{r, eval=FALSE, tidy=FALSE}
# Add objective to minimize expected shortfall
@@ -407,6 +533,7 @@
Key points here are that we are creating 3 new portfolios by reusing the initial portfolio and we are relaxing the box constraints because we are no longer concerned with controlling weight concentration. We have limits on risk contribution.
-->
+---
## Run Optimization
```{r, eval=FALSE, tidy=FALSE}
@@ -424,9 +551,13 @@
explain how portf is a list of portfolios and passed to optimize.portfolio
-->
+---
+
## Plot in Risk-Return Space
![](optimization_figures/opt_minES.png)
+---
+
## Chart Risk Budgets
```{r, eval=FALSE, tidy=FALSE}
chart.RiskBudget(opt.minES[[2]], main="Risk Budget Limit",
@@ -438,6 +569,8 @@
![](optimization_figures/rb_minES.png)
![](optimization_figures/eqrb_minES.png)
+---
+
## Set Rebalancing Parameters and Run Backtest
```{r, eval=FALSE, tidy=FALSE}
# Set rebalancing frequency
@@ -458,18 +591,25 @@
traceDE=0)
```
+---
+
## Min ES Risk Contributions and Weights Through Time
![](optimization_figures/risk_minES.png)
![](optimization_figures/weights_minES.png)
+---
+
## Min ES Risk Budget Limit Risk Contributions and Weights Through Time
![](optimization_figures/risk_minESRB.png)
![](optimization_figures/weights_minESRB.png)
+---
+
## Min ES Equal Component Contribution Risk Contributions and Weights Through Time
![](optimization_figures/risk_minESEqRB.png)
![](optimization_figures/weights_minESEqRB.png)
+---
## Compute Returns and Chart Performance
```{r, eval=FALSE, tidy=FALSE}
@@ -480,18 +620,23 @@
```
![](optimization_figures/ret_minES.png)
+---
-# Example 4
-
-## Maximize CRRA
+## Example 4: Maximize CRRA
Consider an allocation to hedge funds using the EDHEC-Risk Alternative Index as a proxy. Our objective to maximize the fourth order expansion of the Constant Relative Risk Aversion (CRRA) expected utility function as in the Boudt paper and Martinelli paper. We use the same data as Example 3.
-TODO: Add equation
+$$
+EU_{\lambda}(w) = - \frac{\lambda}{2} m_{(2)}(w) +
+\frac{\lambda (\lambda + 1)}{6} m_{(3)}(w) -
+\frac{\lambda (\lambda + 1) (\lambda + 2)}{24} m_{(4)}(w)
+$$
+---
+
## Define a function to compute CRRA
```{r, eval=FALSE, tidy=FALSE}
CRRA <- function(R, weights, lambda, sigma, m3, m4){
@@ -511,6 +656,8 @@
The function arguments should have 'R' as the name of the returns and 'weights' as the name of the weights. 'R' and 'weights' are automatically matched, any other function arguments can be passed in through arguments in add.objective.
-->
+---
+
## Specify Portfolio
```{r, eval=FALSE, tidy=FALSE}
# Specify portfolio
@@ -528,12 +675,20 @@
# Add objective to maximize CRRA
portf.crra <- add.objective(portf.crra, type="return",
name="CRRA", arguments=list(lambda=10))
+
+# I just want these for plotting
+# Set multiplier=0 so that it is calculated, but does not affect the optimization
+portf.crra <- add.objective(portf.crra, type="return", name="mean", multiplier=0)
+portf.crra <- add.objective(portf.crra, type="risk", name="ES", multiplier=0)
+portf.crra <- add.objective(portf.crra, type="risk", name="StdDev", multiplier=0)
```
+---
+
## Run Optimization
```{r, eval=FALSE, tidy=FALSE}
opt.crra <- optimize.portfolio(R, portf.crra, optimize_method="DEoptim",
@@ -541,14 +696,31 @@
momentFUN="crra.moments")
```
+```{r, echo=FALSE}
+load("optimization_results/opt.crra.rda")
+```
+```{r, tidy=FALSE, cache=TRUE}
+opt.crra
+```
+
+
+---
+
## Chart Results
+```{r, eval=FALSE}
+chart.RiskReward(opt.crra, risk.col="ES")
+chart.RiskReward(opt.crra, risk.col="StdDev")
+```
+
![](optimization_figures/crra_RR_ES.png)
![](optimization_figures/crra_RR_StdDev.png)
+---
+
## Run Backtest and Compute Returns
```{r, eval=FALSE, tidy=FALSE}
bt.opt.crra <- optimize.portfolio.rebalancing(R, portf.crra,
@@ -568,6 +740,8 @@
Run optimization and extract the portfolio rebalancing returns from the summary method
-->
+---
+
## Chart Performance
```{r, eval=FALSE, tidy=FALSE}
charts.PerformanceSummary(cbind(ret.bt.opt, ret.crra),
@@ -575,8 +749,14 @@
```
![](optimization_figures/ret_crra.png)
-# Conclusion
+---
+## Conclusion
+TODO
+
+* Overview of what was covered
+* Additional information and plans for PortfolioAnalytics
+
## Acknowledgements
Many thanks to
@@ -591,7 +771,10 @@
- Google for funding the Google Summer of Code for PortfolioAnalytics and many other proposals for R
-->
-## References
+---
+
+## References and Useful Links
+
* [ROI](http://cran.r-project.org/web/packages/ROI/index.html)
* [DEoptim](http://cran.r-project.org/web/packages/DEoptim/index.html)
* [pso](http://cran.r-project.org/web/packages/pso/index.html)
@@ -602,4 +785,4 @@
* Martinelli paper
* Boudt paper
* [PortfolioAnalytics on R-Forge](https://r-forge.r-project.org/projects/returnanalytics/)
-* Shiny App?
+* [Shiny App](http://spark.rstudio.com/rossbennett3/PortfolioOptimization/)
Modified: pkg/PortfolioAnalytics/sandbox/RFinance2014/presentation.md
===================================================================
--- pkg/PortfolioAnalytics/sandbox/RFinance2014/presentation.md 2014-04-21 03:47:59 UTC (rev 3376)
+++ pkg/PortfolioAnalytics/sandbox/RFinance2014/presentation.md 2014-04-27 02:53:24 UTC (rev 3377)
@@ -1,14 +1,31 @@
-% R/Finance 2014: Complex Portfolio Optimization with PortfolioAnalytics
-% Ross Bennett
-% May 16, 2014
+---
+title : Complex Portfolio Optimization with PortfolioAnalytics
+subtitle : R/Finance 2014
+author : Ross Bennett
+date : May 16, 2014
+---
-# Overview
+
+
+
+
+## Overview
* Discuss Portfolio Optimization
* Introduce PortfolioAnalytics
* Demonstrate PortfolioAnalytics with Examples
-# Portfolio Optimization
+
+---
+
## Modern Portfolio Theory
"Modern" Portfolio Theory (MPT) was introduced by Harry Markowitz in 1952.
@@ -22,9 +39,11 @@
How do we define risk? What about more complex objectives?
+---
+
## Portfolio Optimization Objectives
* Minimize Risk
* Volatility
@@ -43,10 +62,9 @@
The challenge here is knowing what solver to use and the capabilities/limits of the chosen solver. Talk about pros/cons of closed-form solvers vs. global solvers and what objectives can be solved.
-->
-# PortfolioAnalytics
+---
-## Overview
-
+## PortfolioAnalytics Overview
PortfolioAnalytics is an R package designed to provide numerical solutions and visualizations for portfolio optimization problems with complex constraints and objectives.
* Support for multiple constraint and objective types
@@ -69,9 +87,9 @@
- Periodic rebalancing and analyzing out of sample performance will help refine objectives and constraints
-->
+---
## Support Multiple Solvers
-
Linear and Quadratic Programming Solvers
* R Optimization Infrastructure (ROI)
@@ -90,6 +108,8 @@
Brief explanation of each solver and what optimization problems (constraints and objectives) are supported
-->
+---
+
## Random Portfolios
PortfolioAnalytics has three methods to generate random portfolios.
@@ -107,18 +127,25 @@
The grid method to generate random portfolios is based on the gridSearch function in NMOF package. The grid search method only satisfies the min and max box constraints. The min_sum and max_sum leverage constraint will likely be violated and the weights in the random portfolios should be normalized. Normalization may cause the box constraints to be violated and will be penalized in constrained_objective.
-->
+---
+
## Comparison of Random Portfolio Methods
![](optimization_figures/rp_plot.png)
+
+
+---
+
## Random Portfolios: Simplex Method
![](optimization_figures/fev_plot.png)
+---
## Workflow
-TODO: Add a nice graphic here (Guy might have one)
+![](misc_figures/workflow.png)
-Specify a Portfolio --> Add Constraints --> Add Objectives --> Run Optimization --> Analyze Results
-
+---
-# Example 1
+## Workflow: Specify Portfolio
-## Data Setup
+```r
+args(portfolio.spec)
+```
+
+```
+## function (assets = NULL, category_labels = NULL, weight_seq = NULL,
+## message = FALSE)
+## NULL
+```
+
+
+---
+
+## Workflow: Add Constraints
+
+```r
+args(add.constraint)
+```
+
+```
+## function (portfolio, type, enabled = TRUE, message = FALSE, ...,
+## indexnum = NULL)
+## NULL
+```
+
+
+Supported Constraint Types
+
+* Sum of Weights
+* Box
+* Group
+* Turnover
+* Diversification
+* Position Limit
+* Return
+* Factor Exposure
+
+---
+
+## Workflow: Add Objectives
+
+```r
+args(add.objective)
+```
+
+```
+## function (portfolio, constraints = NULL, type, name, arguments = NULL,
+## enabled = TRUE, ..., indexnum = NULL)
+## NULL
+```
+
+
+Supported Objective types
+
+* Return
+* Risk
+* Risk Budget
+* Weight Concentration
+
+---
+
+## Workflow: Run Optimization
+
+```r
+args(optimize.portfolio)
+```
+
+```
+## function (R, portfolio = NULL, constraints = NULL, objectives = NULL,
+## optimize_method = c("DEoptim", "random", "ROI", "pso", "GenSA"),
+## search_size = 20000, trace = FALSE, ..., rp = NULL, momentFUN = "set.portfolio.moments",
+## message = FALSE)
+## NULL
+```
+
+```r
+args(optimize.portfolio.rebalancing)
+```
+
+```
+## function (R, portfolio = NULL, constraints = NULL, objectives = NULL,
+## optimize_method = c("DEoptim", "random", "ROI"), search_size = 20000,
+## trace = FALSE, ..., rp = NULL, rebalance_on = NULL, training_period = NULL,
+## trailing_periods = NULL)
+## NULL
+```
+
+
+Supported Optimization Methods
+
+* ROI
+* random
+* DEoptim
+* pso
+* GenSA
+
+---
+
+## Workflow: Analyze Results
+
+Charting Functions
+
+* plot
+* chart.Concentration
+* chart.EfficientFrontier
+* chart.RiskBudget
+* chart.RiskReward
+* chart.Weights
+
+Extract Functions
+
+* extractObjectiveMeasures
+* extractStats
+* extractWeights
+
+
+
+---
+
+## Example 1: Data Setup
Here we will look at portfolio optimization in the context of stocks.
* Selection of large cap, mid cap, and small cap stocks from CRSP data
@@ -147,16 +296,26 @@
```
+---
+
## Distribution of Monthly Returns
![](data_figures/equity_box.png)
+---
+
## Minimum Variance Portfolio
-Consider a portfolio of stocks. Our objective to minimize portfolio variance subect to full investment and box constraints. We will use out of sample backtesting to compare the sample covariance matrix estimate and a Ledoit-Wolf shinkage estimate.
+Here we consider a portfolio of stocks. Our objective is to minimize portfolio variance subect to full investment and box constraints. We will use out of sample backtesting to compare the sample covariance matrix estimate and a Ledoit-Wolf shinkage estimate.
+$$
+\min_{w} w^{T} \Sigma w
+$$
+
+---
+
## Specify Portfolio
```r
@@ -168,8 +327,8 @@
portf.minvar <- add.constraint(portf.init, type = "full_investment")
# Add box constraint such that no asset can have a weight of greater than
-# 20% or less than 1%
-portf.minvar <- add.constraint(portf.minvar, type = "box", min = 0.01, max = 0.2)
+# 45% or less than 1%
+portf.minvar <- add.constraint(portf.minvar, type = "box", min = 0.01, max = 0.45)
# Add objective to minimize portfolio variance
portf.minvar <- add.objective(portf.minvar, type = "risk", name = "var")
@@ -180,6 +339,8 @@
Talk a little about adding constraints and objectives
-->
+---
+
## Ledoit-Wolf Shrinkage Estimate
The default function for `momentFUN` is `set.portfolio.moments`. We need to write our own function to estimate the covariance matrix.
@@ -193,43 +354,34 @@
```
-## Backtesting Parameters
+---
-```r
-# Set rebalancing frequency
-rebal.freq <- "quarters"
-
-# Training Period
-training <- 400
-
-# Trailing Period
-trailing <- 250
-```
-
-
-
## Run Optimization
```r
# Backtest using sample covariance matrix estimate
opt.minVarSample <- optimize.portfolio.rebalancing(equity.data, portf.minvar,
optimize_method="ROI",
- rebalance_on=rebal.freq,
- training_period=training,
- trailing_periods=trailing)
+ rebalance_on="quarters",
+ training_period=400,
+ trailing_periods=250)
# Backtest using Ledoit-Wolf shrinkage covariance matrix estimate
[TRUNCATED]
To get the complete diff run:
svnlook diff /svnroot/returnanalytics -r 3377
From noreply at r-forge.r-project.org Mon Apr 28 23:43:21 2014
From: noreply at r-forge.r-project.org (noreply at r-forge.r-project.org)
Date: Mon, 28 Apr 2014 23:43:21 +0200 (CEST)
Subject: [Returnanalytics-commits] r3378 - in pkg/PortfolioAnalytics: R
vignettes
Message-ID: <20140428214321.DDCAD18444D@r-forge.r-project.org>
Author: rossbennett34
Date: 2014-04-28 23:43:21 +0200 (Mon, 28 Apr 2014)
New Revision: 3378
Modified:
pkg/PortfolioAnalytics/R/charts.DE.R
pkg/PortfolioAnalytics/R/charts.risk.R
pkg/PortfolioAnalytics/vignettes/DesignThoughts.Rnw
Log:
Minor fix to charting functions Add index entry to vignette
Modified: pkg/PortfolioAnalytics/R/charts.DE.R
===================================================================
--- pkg/PortfolioAnalytics/R/charts.DE.R 2014-04-27 02:53:24 UTC (rev 3377)
+++ pkg/PortfolioAnalytics/R/charts.DE.R 2014-04-28 21:43:21 UTC (rev 3378)
@@ -226,7 +226,7 @@
# Only attempt to draw trajectory if rows is greater than or equal to 1
# There may be some corner cases where nrow(w.traj) is equal to 0,
# resulting in a 'subscript out of bounds' error.
- if(rows >= 1){
+ if(rows >= 2){
rr = matrix(nrow=rows, ncol=2)
## maybe rewrite as an apply statement by row on w.traj
rtc = NULL
Modified: pkg/PortfolioAnalytics/R/charts.risk.R
===================================================================
--- pkg/PortfolioAnalytics/R/charts.risk.R 2014-04-27 02:53:24 UTC (rev 3377)
+++ pkg/PortfolioAnalytics/R/charts.risk.R 2014-04-28 21:43:21 UTC (rev 3378)
@@ -221,6 +221,7 @@
rbcols <- grep(paste(match.col, "contribution", sep="."), colnames(rebal.obj))
if(length(rbcols) < 1) stop(paste("No ", match.col, ".contribution columns.", sep=""))
rbdata <- rebal.obj[, rbcols]
+ colnames(rbdata) <- gsub("^.*\\.", "", colnames(rbdata))
chart.StackedBar(w=rbdata, ylab=paste(match.col, "Contribution", sep=" "), main=main, ...)
}
@@ -228,6 +229,7 @@
rbcols <- grep(paste(match.col, "pct_contrib", sep="."), colnames(rebal.obj))
if(length(rbcols) < 1) stop(paste("No ", match.col, ".pct_contrib columns.", sep=""))
rbdata <- rebal.obj[, rbcols]
+ colnames(rbdata) <- gsub("^.*\\.", "", colnames(rbdata))
chart.StackedBar(w=rbdata, ylab=paste(match.col, "% Contribution", sep=" "), main=main, ...)
}
}
Modified: pkg/PortfolioAnalytics/vignettes/DesignThoughts.Rnw
===================================================================
--- pkg/PortfolioAnalytics/vignettes/DesignThoughts.Rnw 2014-04-27 02:53:24 UTC (rev 3377)
+++ pkg/PortfolioAnalytics/vignettes/DesignThoughts.Rnw 2014-04-28 21:43:21 UTC (rev 3378)
@@ -67,6 +67,8 @@
\newcommand{\comm}[1]{\begin{quote}{\large \bf (#1)}\end{quote}}
+% \VignetteIndexEntry{Design Thoughts of the PortfolioAnalytics Package}
+
\begin{document}
\vspace{-2cm}
%\baselineskip=20pt