% \VignetteIndexEntry{Functions for portfolio selection} % \VignetteKeyword{optimize} \documentclass[a4paper]{article} \usepackage[left=2.5cm,top=2cm, bottom=3cm, right=3.5cm]{geometry} \usepackage[noae]{Sweave} \usepackage{mathptmx} \usepackage{amsmath,amstext} \usepackage{hyperref} \usepackage{natbib} \usepackage{units} \usepackage{color} \definecolor{grau2}{rgb}{.2,.2,.2} \definecolor{grau7}{rgb}{.7,.7,.7} % define *Sweave* layout \DefineVerbatimEnvironment{Sinput}{Verbatim}{} \DefineVerbatimEnvironment{Soutput}{Verbatim}{frame=single,xleftmargin=0em,% formatcom=\color{grau2},rulecolor=\color{grau7}} \DefineVerbatimEnvironment{Scode}{Verbatim}{xleftmargin=2em} \fvset{listparameters={\setlength{\topsep}{0pt}}} \renewenvironment{Schunk}{\vspace{\topsep}}{\vspace{\topsep}} <>= options(continue = " ", digits = 3, width = 60, useFancyQuotes = FALSE, max.print = 1000, width = 65) pv <- packageVersion("NMOF") pv <- gsub("(.*)[.](.*)", "\\1-\\2", pv) if (!requireNamespace("quadprog", quietly = TRUE)) trackingPortfolio <- mvFrontier <- mvPortfolio <- minvar <- function(...) { cat("package", sQuote("quadprog"), " is required") invisible(NULL) } @ \begin{document} {\raggedright{\LARGE Functions for portfolio selection}}\hspace*{\fill} {\footnotesize Package version~\Sexpr{pv}}\medskip \noindent Enrico Schumann\\ \noindent \texttt{es@enricoschumann.net}\\ \noindent \url{https://CRAN.R-project.org/package=NMOF}\\ \bigskip \noindent A main topic of \citet{Gilli2019} is non-standard portfolio-selection models; see Chapters~12--14. Nevertheless, the \texttt{NMOF} package also offers several functions that help with standard portfolio models, i.e. models that can be solved with traditional optimisation techniques such as quadratic programming. <>= library("NMOF") @ \section{Minimum-variance portfolios} <>= var <- structure( c(0.000988087100677907, -0.0000179669410403153, 0.000368923882626859, 0.000208303611101873, 0.000262742052359594, -0.0000179669410403153, 0.00171852167358765, 0.0000857467457561209, 0.0000215059246610556, 0.0000283532159921211, 0.000368923882626859, 0.0000857467457561209, 0.00075871953281751, 0.000194002299424151, 0.000188824454515841, 0.000208303611101873, 0.0000215059246610556, 0.000194002299424151, 0.000265780633005374, 0.000132611196599808, 0.000262742052359594, 0.0000283532159921211, 0.000188824454515841, 0.000132611196599808, 0.00025948420130626), .Dim = c(5L, 5L), .Dimnames = list(c("CBK.DE", "VOW.DE", "CON.DE", "LIN.DE", "MUV2.DE"), c("CBK.DE", "VOW.DE", "CON.DE", "LIN.DE", "MUV2.DE"))) @ \noindent The function \texttt{minvar}\marginpar{\footnotesize\texttt{minvar}} computes the minimum-variance portfolio for a given variance--covariance matrix, subject to holding-size constraints. As example data, the variable \texttt{var} contains a small variance--covariance matrix, computed from daily returns of five German stocks. The data are taken from \url{http://enricoschumann.net/data/gilli_accuracy.html}\,; the code to build the matrix is in the source file of this vignette. <>= var @ \noindent An example call, with minimum and maximum holding sizes specified. <>= minvar(var, wmin = 0, wmax = 0.5) @ \noindent The function returns the portfolio weights with an attribute \texttt{variance} that provides the variance of this portfolio. The holding size constraints can also be specified as vectors, with different values for different assets. <>= minvar(var, wmin = c(0.1, 0, 0, 0, 0), ## enforce at least 10% weight in CBK.DE wmax = 0.5) @ \noindent Use \texttt{Inf} to switch off weight constraints. <>= minvar(var, wmin = -Inf, wmax = Inf) ## no bounds minvar(var, wmin = -Inf, wmax = 0.45) ## no lower bounds minvar(var, wmin = 0.1, wmax = Inf) ## no upper bounds @ \noindent The function also supports group constraints: <>= ## group 1 consists of asset 1 only, and must have weight [0.25,0.30] ## group 2 consists of assets 4 and 5, and must have weight [0.10,0.20] minvar(var, wmin = 0, wmax = 0.40, groups = list(1, 4:5), groups.wmin = c(0.25, 0.1), groups.wmax = c(0.30, 0.2)) @ \noindent Alternatively, group constraints can be specified through group names instead of positions. <<>>= ## group A consists of asset 1 only, and must have weight [0.25,0.30] ## group B consists of assets 4 and 5, and must have weight [0.10,0.20] minvar(var, wmin = 0, wmax = 0.40, groups = c("A", "none", "none", "B", "B"), groups.wmin = c(A = 0.25, B = 0.1), groups.wmax = c(A = 0.30, B = 0.2)) @ \section{Mean--variance efficient portfolios and frontiers} \noindent The function \texttt{mvPortfolio}\marginpar{\footnotesize\texttt{mvPortfolio}} computes a mean--variance-efficient portfolio for a given variance--covariance matrix and mean-return assumption, subject to holding-size constraints. We make up some data for four assets, with a constant correlation of~0.5. <>= vols <- c(0.10, 0.15, 0.20, 0.22) ## expected vols m <- c(0.06, 0.12, 0.09, 0.07) ## expected mean returns const_cor <- function(rho, na) { C <- array(rho, dim = c(na, na)) diag(C) <- 1 C } var <- diag(vols) %*% const_cor(0.5, length(vols)) %*% diag(vols) @ \medskip \noindent One way to compute a mean--variance-efficient portfolio is by requiring a minimum return. <>= mvPortfolio(m, var, min.return = 0.08, wmax = 1) mvPortfolio(m, var, min.return = 0.10, wmax = 1) mvPortfolio(m, var, min.return = 0.12, wmax = 1) @ \noindent Alternatively, we may specify a trade-off between return and variance and minimise \begin{equation*} -\lambda \mbox{\texttt{m}}'w + \frac{1}{2}(1-\lambda) w'\mbox{\texttt{var}\,}w\,, \end{equation*} in which~$w$ are the weights. If $\lambda$ is a vector of length~2, then the function minimises \begin{equation*} -\lambda_1 \mbox{\texttt{m}\,}'w + \frac{1}{2}\lambda_2 w'\mbox{\texttt{var}\,}w\,. \end{equation*} \medskip \noindent The function \texttt{mvFrontier}\marginpar{\footnotesize\texttt{mvFrontier}} traces out a whole frontier of mean--variance efficient portfolios. (But see the discussion on frontiers in Chapter~14 of \citealp{Gilli2019}.) <>= if (requireNamespace("quadprog")) { wmin <- 0 wmax <- 1 p1 <- mvFrontier(m, var, wmin = wmin, wmax = wmax, n = 50) ## with a 'risk-free' asset rf rf <- 0.02 p2 <- mvFrontier(m, var, wmin = wmin, wmax = wmax, n = 50, rf = rf) par(las = 1, bty = "n", tck = 0.001, ps = 8) plot(p1$volatility, p1$return, pch = 19, cex = 0.5, type = "o", xlab = "Expected volatility", ylab = "Expected return") lines(p2$volatility, p2$return, col = grey(0.5)) abline(v = 0, h = rf) } else plot(1) @ \section{Return-based tracking portfolios} Function \texttt{trackingPortfolio}\marginpar{\footnotesize\texttt{trackingPortfolio}} computes a portfolio that is close to another portfolio in the mean-square\slash{}variance sense. The function to be minimised is determined by argument \texttt{objective}: supported are \texttt{variance} (the default) or \texttt{sum.of.squares}. <<>>= ns <- 120 R <- randomReturns(na = 1 + 10, ## first asset is the benchmark ns = ns, sd = 0.03, mean = 0.005, rho = 0.7) var <- cov(R) trackingPortfolio(var, wmax = 0.4) @ \section{Minimum-Expected-Shortfall portfolios} Function \texttt{minCVaR}\marginpar{\footnotesize\texttt{minCVaR}} computes a portfolio that minimises conditional Value-at-Risk; its default method is the LP approach described in \citet{rockafellar2000}. See \emph{Minimising Conditional Value-at-Risk (CVaR)} (\url{http://enricoschumann.net/notes/minimising-conditional-var.html}) for more details <>= ns <- 5000 ## number of scenarios na <- 20 ## nunber of assets R <- randomReturns(na, ns, sd = 0.01, rho = 0.5) if (requireNamespace("Rglpk")) { ## example requires "Rglpk" package sol <- minCVaR(R, q = 0.1) } else message("Package ", sQuote("Rglpk"), " not available") @ \section{Minimum Mean--Absolute-Deviation portfolios} Function \texttt{minMAD}\marginpar{\footnotesize\texttt{minMAD}} computes a portfolio that minimises the mean absolute-deviation of portfolio returns, as described in \citet{Konno1991}. <>= ns <- 5000 ## number of scenarios na <- 5 ## nunber of assets R <- randomReturns(na, ns, sd = 0.01, rho = 0.5) minMAD(R = R) @ \bibliographystyle{plainnat} \bibliography{NMOF} \end{document}