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
The solver can be specified with the optimize_method
argument in optimize.portfolio
and optimize.portfolio.rebalancing
. The 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 DEoptim package, the particle swarm optimization algorithm via the pso package, the generalized simulated annealing via the GenSA package, and linear and quadratic programming are implemented via the ROI package which acts as an interface to the Rglpk, Rsymphony, and quadprog packages.
A key strength of PortfolioAnalytics is the generalization of constraints and objectives that can be solved.
If optimize_method="ROI"
is specified, a default solver will be selected based on the optimization problem. The glpk
solver is the default solver for LP and MILP optimization problems. The quadprog
solver is the default solver for QP optimization problems. For example, 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:
optimize.portfolio
as an added argument to the portfolio
object).
maxSR=TRUE
in optimize.portfolio
.
If both mean and StdDev are specified as objective names, the default action is to maximize quadratic utility, therefore maxSR=TRUE
must be specified to maximize Sharpe Ratio.
maxSTARR=TRUE
in 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.
Because these convex optimization problem are standardized, there is no need for a penalty term. The multiplier
argument in 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. PortfolioAnalytics provides a random portfolio optimization method and also utilizes the R packages DEoptim, pso, and GenSA for solving non-convex global optimization problems.
PortfolioAnalytics supports three methods of generating random portfolios.
gridSearch
function in package 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 constrained_objective
.
PortfolioAnalytics leverages the PerformanceAnalytics package for many common objective functions. The objective types in PortfolioAnalytics are designed to be used with PerformanceAnalytics functions, but any user supplied valid R function can be used as an objective.
portfolio.spec
function. The main argument to portfolio.spec
is assets
. The 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. Adding constraints to the portfolio object is done with add.constraint
. The 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. Objectives can be added to the portfolio object with add.objective
. The 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 indexnum
argument can be specified. With the constraints and objectives specified in the portfolio object, the portfolio object can be passed to optimize.portfolio
or optimize.portfolio.rebalancing
to run the optimization. Arguments to optimize.portfolio
include asset returns, the portfolio obect specifying constraints and objectives, optimization method, and other parameters specific to the solver. optimize.portfolio.rebalancing
adds support for backtesting portfolio optimization through time with rebalancing or rolling periods.portfolio.spec
, add.constraint
, and add.objective
. The multi-layer portfolio specification object is first initialized by passing the top level portfolio to mult.portfolio.spec
. Sub-portfolios are then added with add.sub.portfolio
. The multi-layer portfolio specification object can then be passed to optimize.portfolio
and optimize.portfolio.rebalancing
. See demo(multi_layer_optimization)
. Support for regime switching models allows one to change constraints and objectives depending on the current regime. Portfolios are created as normal with portfolio.spec
, add.constraint
, and add.objective
. The portfolios are then combined with a regime object using regime.portfolios
to create a regime portfolio specification which can then be passed to optimize.portfolio
and optimize.portfolio.rebalancing
. Regime switching optimization is implemented in such a way that any arbitrary regime model can be used. See demo(regime_switching)
.set.portfolio.moments
function computes the first, second, third, and fourth moments depending on the objective function(s) in the portfolio
object. For example, if the third and fourth moments do not need to be calculated for a given objective, then set.portfolio.moments
will try to detect this and not compute those moments. Currently, set.portfolio.moments
implements methods to compute moments based on sample estimates, higher moments from fitting a statistical factor model based on the work of Kris Boudt, the Black Litterman model, and the Fully Flexible Framework based on the work of Attilio Meucci (NEED REFERENCE HERE). See the Custom Moment and Objective Functions vignette for a more detailed description and examples.chart.Weights
plots the weights of the optimal portfolio. chart.RiskReward
plots the optimal portfolio in risk-reward space. The random portfolios, DEoptim, and pso solvers will return trace portfolio information at each iteration when optimize.portfolio
is run with trace=TRUE
. If this is the case, chart.RiskReward
will plot these portfolios so that the feasible space can be easily visualized. Although the GenSA and ROI solvers do not return trace portfolio information, random portfolios can be be generated with the argument rp=TRUE
in chart.RiskReward
. A plot
function is provided that will plot the weights and risk-reward scatter chart. The component risk contribution can be charted for portfolio optimization problems with risk budget objectives with chart.RiskBudget
. Neighbor portfolios can be plotted in chart.RiskBudget
, chart.Weights
, and chart.RiskReward
. Efficient frontiers can be extracted from optimize.portfolio
objects or created from a portfolio
object. The efficient frontier can be charted in risk-reward space with chart.EfficientFrontier
. The weights along the efficient frontier can be charted with chart.EF.Weights
. Multiple objects created via optimize.portfolio
can be combined with combine.optimizations
for visual comparison. The weights of the optimal portfolios can be plotted with chart.Weights
. The optimal portfolios can be compared in risk-reward space with chart.RiskReward
. The portfolio component risk contributions of the multiple optimal portfolios can be plotted with chart.RiskBudget
.xts
package is used for working with time series data. The PerformanceAnalytics package is used for many common objective functions. The objective types in PortfolioAnalytics are designed to be used with PerformanceAnalytics functions such as StdDev
, VaR
, and ES
. The foreach and iterators packages are used extensively throughout the package to support parallel programming. The primary functions where foreach
loops are used is optimize.portfolio
, optimize.portfolio.rebalancing
, and create.EfficientFrontier
. In addition to a random portfolios optimzation method, PortfolioAnalytics supports backend solvers by leveraging the following packages: DEoptim, pso, GenSA, ROI and associated ROI plugin packages.Chriss, Neil A and Almgren, Robert, Portfolios from Sorts (April 27, 2005). Available at SSRN: http://ssrn.com/abstract=720041 or http://dx.doi.org/10.2139/ssrn.720041
Meucci, Attilio, The Black-Litterman Approach: Original Model and Extensions (August 1, 2008). Shorter version in, THE ENCYCLOPEDIA OF QUANTITATIVE FINANCE, Wiley, 2010. Available at SSRN: http://ssrn.com/abstract=1117574 or http://dx.doi.org/10.2139/ssrn.1117574
Meucci, Attilio, Fully Flexible Views: Theory and Practice (August 8, 2008). Fully Flexible Views: Theory and Practice, Risk, Vol. 21, No. 10, pp. 97-102, October 2008. Available at SSRN: http://ssrn.com/abstract=1213325
Scherer, Bernd and Martin, Doug, Modern Portfolio Optimization. Springer. 2005.
Shaw, William Thornton, Portfolio Optimization for VAR, CVaR, Omega and Utility with General Return Distributions: A Monte Carlo Approach for Long-Only and Bounded Short Portfolios with Optional Robustness and a Simplified Approach to Covariance Matching (June 1, 2011). Available at SSRN: http://ssrn.com/abstract=1856476 or http://dx.doi.org/10.2139/ssrn.1856476
CRAN task view on Optimization http://cran.r-project.org/web/views/Optimization.html
Large-scale portfolio optimization with DEoptim http://cran.r-project.org/web/packages/DEoptim/vignettes/DEoptimPortfolioOptimization.pdf