\documentclass[12pt,letterpaper,english]{article} \usepackage[OT1]{fontenc} \usepackage{Sweave} \usepackage{verbatim} \usepackage{Rd} \usepackage{amsmath} \begin{document} \SweaveOpts{concordance=TRUE} % \VignetteIndexEntry{Portfolio Optimization with ROI in PortfolioAnalytics} \title{Portfolio Optimization with ROI in PortfolioAnalytics} \author{Ross Bennett} \date{May 17, 2018} \maketitle \begin{abstract} The purpose of this vignette is to demonstrate a sample of the optimzation problems that can be solved in PortfolioAnalytics with the ROI solvers. See \code{demo(demo\_ROI)} for a more complete set of examples. \end{abstract} \tableofcontents \section{Getting Started} \subsection{Load Packages} Load the necessary packages. <<>>= suppressMessages(library(PortfolioAnalytics)) suppressMessages(library(foreach)) suppressMessages(library(iterators)) suppressMessages(library(ROI)) suppressMessages(library(ROI.plugin.quadprog)) suppressMessages(library(ROI.plugin.glpk)) @ \subsection{Data} The edhec data set from the PerformanceAnalytics package will be used as example data. <<>>= data(edhec) # Use the first 4 columns in edhec for a returns object returns <- edhec[, 1:4] colnames(returns) <- c("CA", "CTAG", "DS", "EM") print(head(returns, 5)) # Get a character vector of the fund names funds <- colnames(returns) @ \section{Maximizing Mean Return} The objective to maximize mean return is a linear problem of the form: \begin{equation*} \begin{aligned} & \underset{\boldsymbol{w}}{\text{maximize}} & & \hat{\boldsymbol{\mu}}' \boldsymbol{w} \\ \end{aligned} \end{equation*} Where $\hat{\boldsymbol{\mu}}$ is the estimated mean asset returns and $\boldsymbol{w}$ is the set of weights. Because this is a linear problem, it is well suited to be solved using a linear programming solver. For these types of problems, PortfolioAnalytics uses the ROI package with the glpk plugin. \subsection{Portfolio Object} The first step is to create the portfolio object. Then add constraints and a return objective. <>= # Create portfolio object portf_maxret <- portfolio.spec(assets=funds) # Add constraints to the portfolio object portf_maxret <- add.constraint(portfolio=portf_maxret, type="full_investment") portf_maxret <- add.constraint(portfolio=portf_maxret, type="box", min=c(0.02, 0.05, 0.03, 0.02), max=c(0.55, 0.6, 0.65, 0.5)) # Add objective to the portfolio object portf_maxret <- add.objective(portfolio=portf_maxret, type="return", name="mean") @ The print method for the portfolio object shows a high level overview while the summary method shows much more detail of the assets, constraints, and objectives that are specified in the portfolio object. <<>>= print(portf_maxret) summary(portf_maxret) @ \subsection{Optimization} The next step is to run the optimization. Note that \code{optimize\_method="ROI"} is specified in the call to \code{optimize.portfolio} to select the solver used for the optimization. <>= # Run the optimization opt_maxret <- optimize.portfolio(R=returns, portfolio=portf_maxret, optimize_method="ROI", trace=TRUE) @ The print method for the \code{opt\_maxret} object shows the call, optimal weights, and the objective measure <<>>= print(opt_maxret) @ The sumary method for the \code{opt\_maxret} object shows details of the object with constraints, objectives, and other portfolio statistics. <<>>= summary(opt_maxret) @ The \code{opt\_maxret} object is of class \code{optimize.portfolio.ROI} and contains the following elements. Objects of class \code{optimize.portfolio.ROI} are S3 objects and elements can be accessed with the \code{\$} operator. <<>>= names(opt_maxret) @ The optimal weights and value of the objective function at the optimum can be accessed with the \code{extractStats} function. <<>>= extractStats(opt_maxret) @ The optimal weights can be accessed with the \code{extractWeights} function. <<>>= extractWeights(opt_maxret) @ \subsection{Visualization} The \code{plot} method charts of the optimal weights with the box constraints along with the optimal portfolio in risk-return space. The blue dots are the optimal weights and the gray triangles are the \code{min} and \code{max} of the box constraints. <<>>= plot(opt_maxret, chart.assets=TRUE, xlim=c(0.02, 0.18)) @ The optimal portfolio can be plotted in risk-return space along with other feasible portfolios. The return metric is defined in the \code{return.col} argument and the risk metric is defined in the \code{risk.col} argument. The scatter chart includes the optimal portfolio (blue dot) and other feasible portfolios (gray circles) to show the overall feasible space given the constraints. By default, if \code{rp} is not passed in, the feasible portfolios are generated with \code{random\_portfolios} to satisfy the constraints of the portfolio object. Volatility as the risk metric <>= chart.RiskReward(opt_maxret,return.col="mean", risk.col="sd", chart.assets=TRUE, xlim=c(0.01, 0.05), main="Maximum Return") @ \subsection{Backtesting} An out of sample backtest is run with \code{optimize.portfolio.rebalancing}. In this example, an initial training period of 36 months is used and the portfolio is rebalanced quarterly. <>= bt_maxret <- optimize.portfolio.rebalancing(R=returns, portfolio=portf_maxret, optimize_method="ROI", rebalance_on="quarters", training_period=36) @ The \code{bt\_maxret} object is a list containing the optimal weights and objective measure at each rebalance period. \section{Minimizing Portfolio Variance} The objective to minimize portfolio variance is a quadratic problem of the form: \begin{equation*} \begin{aligned} & \underset{\boldsymbol{w}}{\text{minimize}} & & \boldsymbol{w}' \boldsymbol{\Sigma} \boldsymbol{w} \\ \end{aligned} \end{equation*} Where $\boldsymbol{\Sigma}$ is the estimated covariance matrix of asset returns and $\boldsymbol{w}$ is the set of weights. Because this is a quadratic problem, it is well suited to be solved using a quadratic programming solver. For these types of problems, PortfolioAnalytics uses the ROI package with the quadprog plugin. \subsection{Global Minimum Variance Portfolio} \subsubsection{Portfolio Object} <<>>= # Create portfolio object portf_minvar <- portfolio.spec(assets=funds) # Add full investment constraint to the portfolio object portf_minvar <- add.constraint(portfolio=portf_minvar, type="full_investment") # Add objective to minimize variance portf_minvar <- add.objective(portfolio=portf_minvar, type="risk", name="var") @ The only constraint specified is the full investment constraint, therefore the optimization problem is solving for the global minimum variance portfolio. \subsubsection{Optimization} <>= # Run the optimization opt_gmv <- optimize.portfolio(R=returns, portfolio=portf_minvar, optimize_method="ROI", trace=TRUE) print(opt_gmv) @ \subsubsection{Backtesting} <>= bt_gmv <- optimize.portfolio.rebalancing(R=returns, portfolio=portf_minvar, optimize_method="ROI", rebalance_on="quarters", training_period=36) @ \subsection{Constrained Minimum Variance Portfolio} \subsubsection{Portfolio Object} Constraints can be added to the \code{portf\_minvar} portfolio object previously created. <>= # Add long only constraints portf_minvar <- add.constraint(portfolio=portf_minvar, type="box", min=0, max=1) # Add group constraints portf_minvar <- add.constraint(portfolio=portf_minvar, type="group", groups=list(groupA=1, groupB=c(2, 3), groupC=4), group_min=c(0, 0.25, 0.10), group_max=c(0.45, 0.6, 0.5)) @ \subsubsection{Optimization} <>= # Run the optimization opt_minvar <- optimize.portfolio(R=returns, portfolio=portf_minvar, optimize_method="ROI", trace=TRUE) print(opt_minvar) @ \subsubsection{Backtesting} <>= bt_minvar <- optimize.portfolio.rebalancing(R=returns, portfolio=portf_minvar, optimize_method="ROI", rebalance_on="quarters", training_period=36) @ \section{Maximizing Quadratic Utility} The objective to maximize quadratic utility is a quadratic problem of the form: \begin{equation*} \begin{aligned} & \underset{\boldsymbol{w}}{\text{maximize}} & & \boldsymbol{w}' \boldsymbol{\mu} - \frac{\lambda}{2}\boldsymbol{w}' \boldsymbol{\Sigma} \boldsymbol{w} \\ \end{aligned} \end{equation*} Where $\mu$ is the estimated mean asset returns, $\lambda$ is the risk aversion parameter, $\boldsymbol{\Sigma}$ is the estimated covariance matrix of asset returns and $\boldsymbol{w}$ is the set of weights. Quadratic utility maximizes return while penalizing variance. The $\lambda$ risk aversion parameter controls how much portfolio variance is penalized. Because this is a quadratic problem, it is well suited to be solved using a quadratic programming solver. For these types of problems, PortfolioAnalytics uses the ROI package with the quadprog plugin. \subsection{Portfolio Object} The portfolio object is specified, and constraints and objectives are created separately. The constraints and objectives are created separately as an alternative example and could also have been added directly to the portfolio object as in the previous sections. <<>>= # Create initial portfolio object init_portf <- portfolio.spec(assets=funds) # Create full investment constraint fi_constr <- weight_sum_constraint(type="full_investment") # Create long only constraint lo_constr <- box_constraint(type="long_only", assets=init_portf$assets) # Combine the constraints in a list qu_constr <- list(fi_constr, lo_constr) # Create return objective ret_obj <- return_objective(name="mean") # Create variance objective specifying a risk_aversion parameter which controls # how much the variance is penalized var_obj <- portfolio_risk_objective(name="var", risk_aversion=0.25) # Combine the objectives into a list qu_obj <- list(ret_obj, var_obj) @ \subsection{Optimization} Note how the constraints and objectives are passed to optimize.portfolio. <>= # Run the optimization opt_qu <- optimize.portfolio(R=returns, portfolio=init_portf, constraints=qu_constr, objectives=qu_obj, optimize_method="ROI", trace=TRUE) @ \subsection{Backtesting} <>= bt_qu <- optimize.portfolio.rebalancing(R=returns, portfolio=init_portf, constraints=qu_constr, objectives=qu_obj, optimize_method="ROI", rebalance_on="quarters", training_period=36) @ \section{Minimizing Expected Tail Loss} TODO \end{document}