Path: blob/master/vignettes/ROI_vignette.Rnw
1433 views
\documentclass[12pt,letterpaper,english]{article}1\usepackage[OT1]{fontenc}2\usepackage{Sweave}3\usepackage{verbatim}4\usepackage{Rd}5\usepackage{amsmath}67\begin{document}8\SweaveOpts{concordance=TRUE}910% \VignetteIndexEntry{Portfolio Optimization with ROI in PortfolioAnalytics}1112\title{Portfolio Optimization with ROI in PortfolioAnalytics}13\author{Ross Bennett}1415\date{May 17, 2018}16\maketitle1718\begin{abstract}19The 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.20\end{abstract}2122\tableofcontents2324\section{Getting Started}25\subsection{Load Packages}26Load the necessary packages.27<<>>=28suppressMessages(library(PortfolioAnalytics))29suppressMessages(library(foreach))30suppressMessages(library(iterators))31suppressMessages(library(ROI))32suppressMessages(library(ROI.plugin.quadprog))33suppressMessages(library(ROI.plugin.glpk))34@3536\subsection{Data}37The edhec data set from the PerformanceAnalytics package will be used as example data.38<<>>=39data(edhec)4041# Use the first 4 columns in edhec for a returns object42returns <- edhec[, 1:4]43colnames(returns) <- c("CA", "CTAG", "DS", "EM")44print(head(returns, 5))4546# Get a character vector of the fund names47funds <- colnames(returns)48@495051\section{Maximizing Mean Return}52The objective to maximize mean return is a linear problem of the form:53\begin{equation*}54\begin{aligned}55& \underset{\boldsymbol{w}}{\text{maximize}}56& & \hat{\boldsymbol{\mu}}' \boldsymbol{w} \\57\end{aligned}58\end{equation*}5960Where $\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.6162\subsection{Portfolio Object}6364The first step is to create the portfolio object. Then add constraints and a return objective.65<<tidy=FALSE>>=66# Create portfolio object67portf_maxret <- portfolio.spec(assets=funds)6869# Add constraints to the portfolio object70portf_maxret <- add.constraint(portfolio=portf_maxret, type="full_investment")71portf_maxret <- add.constraint(portfolio=portf_maxret, type="box",72min=c(0.02, 0.05, 0.03, 0.02),73max=c(0.55, 0.6, 0.65, 0.5))7475# Add objective to the portfolio object76portf_maxret <- add.objective(portfolio=portf_maxret, type="return", name="mean")77@7879The 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.80<<>>=81print(portf_maxret)82summary(portf_maxret)83@8485\subsection{Optimization}86The 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.87<<tidy=FALSE>>=88# Run the optimization89opt_maxret <- optimize.portfolio(R=returns, portfolio=portf_maxret,90optimize_method="ROI", trace=TRUE)91@9293The print method for the \code{opt\_maxret} object shows the call, optimal weights, and the objective measure94<<>>=95print(opt_maxret)96@9798The sumary method for the \code{opt\_maxret} object shows details of the object with constraints, objectives, and other portfolio statistics.99<<>>=100summary(opt_maxret)101@102103104The \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.105<<>>=106names(opt_maxret)107@108109The optimal weights and value of the objective function at the optimum can be accessed with the \code{extractStats} function.110<<>>=111extractStats(opt_maxret)112@113114The optimal weights can be accessed with the \code{extractWeights} function.115<<>>=116extractWeights(opt_maxret)117@118119\subsection{Visualization}120The \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.121<<>>=122plot(opt_maxret, chart.assets=TRUE, xlim=c(0.02, 0.18))123@124125The 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.126127Volatility as the risk metric128<<tidy=FALSE, fig.align='center',fig.height=5, fig.width=5>>=129chart.RiskReward(opt_maxret,return.col="mean", risk.col="sd",130chart.assets=TRUE, xlim=c(0.01, 0.05), main="Maximum Return")131@132133\subsection{Backtesting}134An 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.135<<tidy=FALSE>>=136bt_maxret <- optimize.portfolio.rebalancing(R=returns, portfolio=portf_maxret,137optimize_method="ROI",138rebalance_on="quarters",139training_period=36)140@141142The \code{bt\_maxret} object is a list containing the optimal weights and objective measure at each rebalance period.143144\section{Minimizing Portfolio Variance}145The objective to minimize portfolio variance is a quadratic problem of the form:146\begin{equation*}147\begin{aligned}148& \underset{\boldsymbol{w}}{\text{minimize}}149& & \boldsymbol{w}' \boldsymbol{\Sigma} \boldsymbol{w} \\150\end{aligned}151\end{equation*}152153Where $\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.154155\subsection{Global Minimum Variance Portfolio}156\subsubsection{Portfolio Object}157<<>>=158# Create portfolio object159portf_minvar <- portfolio.spec(assets=funds)160161# Add full investment constraint to the portfolio object162portf_minvar <- add.constraint(portfolio=portf_minvar, type="full_investment")163164# Add objective to minimize variance165portf_minvar <- add.objective(portfolio=portf_minvar, type="risk", name="var")166@167168The only constraint specified is the full investment constraint, therefore the optimization problem is solving for the global minimum variance portfolio.169170\subsubsection{Optimization}171<<tidy=FALSE>>=172# Run the optimization173opt_gmv <- optimize.portfolio(R=returns, portfolio=portf_minvar,174optimize_method="ROI", trace=TRUE)175print(opt_gmv)176@177178\subsubsection{Backtesting}179<<tidy=FALSE>>=180bt_gmv <- optimize.portfolio.rebalancing(R=returns, portfolio=portf_minvar,181optimize_method="ROI",182rebalance_on="quarters",183training_period=36)184@185186187\subsection{Constrained Minimum Variance Portfolio}188189\subsubsection{Portfolio Object}190Constraints can be added to the \code{portf\_minvar} portfolio object previously created.191<<tidy=FALSE>>=192# Add long only constraints193portf_minvar <- add.constraint(portfolio=portf_minvar, type="box",194min=0, max=1)195196# Add group constraints197portf_minvar <- add.constraint(portfolio=portf_minvar,198type="group",199groups=list(groupA=1,200groupB=c(2, 3),201groupC=4),202group_min=c(0, 0.25, 0.10),203group_max=c(0.45, 0.6, 0.5))204@205206\subsubsection{Optimization}207<<tidy=FALSE>>=208# Run the optimization209opt_minvar <- optimize.portfolio(R=returns, portfolio=portf_minvar,210optimize_method="ROI", trace=TRUE)211print(opt_minvar)212@213214\subsubsection{Backtesting}215<<tidy=FALSE>>=216bt_minvar <- optimize.portfolio.rebalancing(R=returns, portfolio=portf_minvar,217optimize_method="ROI",218rebalance_on="quarters",219training_period=36)220@221222\section{Maximizing Quadratic Utility}223The objective to maximize quadratic utility is a quadratic problem of the form:224\begin{equation*}225\begin{aligned}226& \underset{\boldsymbol{w}}{\text{maximize}}227& & \boldsymbol{w}' \boldsymbol{\mu} - \frac{\lambda}{2}\boldsymbol{w}' \boldsymbol{\Sigma} \boldsymbol{w} \\228\end{aligned}229\end{equation*}230231Where $\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.232233\subsection{Portfolio Object}234The 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.235<<>>=236# Create initial portfolio object237init_portf <- portfolio.spec(assets=funds)238239# Create full investment constraint240fi_constr <- weight_sum_constraint(type="full_investment")241242# Create long only constraint243lo_constr <- box_constraint(type="long_only", assets=init_portf$assets)244245# Combine the constraints in a list246qu_constr <- list(fi_constr, lo_constr)247248# Create return objective249ret_obj <- return_objective(name="mean")250251# Create variance objective specifying a risk_aversion parameter which controls252# how much the variance is penalized253var_obj <- portfolio_risk_objective(name="var", risk_aversion=0.25)254255# Combine the objectives into a list256qu_obj <- list(ret_obj, var_obj)257@258259\subsection{Optimization}260Note how the constraints and objectives are passed to optimize.portfolio.261<<tidy=FALSE>>=262# Run the optimization263opt_qu <- optimize.portfolio(R=returns, portfolio=init_portf,264constraints=qu_constr,265objectives=qu_obj,266optimize_method="ROI",267trace=TRUE)268@269270\subsection{Backtesting}271<<tidy=FALSE>>=272bt_qu <- optimize.portfolio.rebalancing(R=returns, portfolio=init_portf,273constraints=qu_constr,274objectives=qu_obj,275optimize_method="ROI",276rebalance_on="quarters",277training_period=36)278@279280\section{Minimizing Expected Tail Loss}281TODO282283\end{document}284285