# Computing the global minimum-variance portfolio

This tutorial appeared originally on the COMISEF Wiki.

## 1 The problem

The global minimum-variance (MV) portfolio is the leftmost point of the meanâ€“variance efficient frontier. It is found by choosing portfolio weights that minimise overall variance subject only to the constraint that the sum of the weights $$w$$ is one. Formally,

$$\min_{w}\ \ w' \Sigma w\\ w'\iota = 1$$

where $$w$$ is the vector of portfolio weights, $$\Sigma$$ is the variance-covariance matrix of the assets, and $$\iota$$ is an appropriately-sized vector of ones. We do not put any further constraints on the problem; short sales, in particular, are allowed here.

As an example dataset, we create artificial returns with mean zero (the default with rnorm) and volatility 5%. (This order of magnitude would be reasonable for monthly equity returns.) These returns are stored in a matrix mData.

nO <- 100L  ## number of observations
nA <- 10L   ## number of assets
mData <- array(rnorm(nO * nA, sd = 0.05),
dim = c(nO, nA))


We first use the solve.QP function of package quadprog (see the references below), so we load/attach the package.

library("quadprog")


The aim will be to minimise w %*% cov(mData) %*% w, subject to the constraint that sum(w) equals one.

aMat <- array(1, dim = c(1,nA))
bVec <- 1
zeros <- array(0, dim = c(nA,1))
solQP <- solve.QP(cov(mData), zeros, t(aMat), bVec, meq = 1)
solQP$solution  [1] 0.07853404 0.12853164 0.14526751 0.09211099 0.11893845 [6] 0.15176486 0.12447023 0.02945822 0.06584904 0.06507502  The quadprod package will minimise $$\frac{1}{2} w' \Sigma w$$, i.e. one-half of the portfolio variance (see ?solve.QP). Hence the returned minimum-value will be one-half of the portfolio's variance. Check: all.equal(drop(var(mData %*% solQP$solution)),  ## the solution, evaluated at the data
2*solQP$value) ## the solution's objective fun value times 2  [1] TRUE  This computation is also included as function minvar in the NMOF package. require("NMOF") minvar(cov(mData), wmin = -Inf, wmax = Inf)   [1] 0.07853404 0.12853164 0.14526751 0.09211099 0.11893845 [6] 0.15176486 0.12447023 0.02945822 0.06584904 0.06507502 attr(,"variance") [1] 0.0002269999  Note that NMOF's minvar also returns the portfolio variance. drop(var(mData %*% solQP$solution))

[1] 0.0002269999


## 3 A regression solution

The problem can also be solved as a linear regression; see Kempf and Memmel (2006). The authors show that regressing the negative excess returns of $$r_{\mathrm{n_A}} - 1$$ assets on the returns of the remaining asset results in coefficients that equal the $$r_{\mathrm{n_A}} - 1$$ respective portfolio weights; the remaining asset's weight is determined by the budget constraint. (Excess return here means with respect to the remaining asset.)

We run the regression

$$r_{\mathrm{n_A}} = \alpha + w_1 (r_{\mathrm{n_A}} - r_1) + w_2 (r_{\mathrm{n_A}} - r_2) + \cdots + w_{\mathrm{n_A}-1}(r_{\mathrm{n_A}}-r_{\mathrm{n_A}-1}) + \epsilon\,,$$

in which $$r_i$$ are the returns of the i-th asset, and $$\epsilon$$ are the errors.

From this equation, we directly obtain the weights $$w_1$$ to $$w_{\mathrm{n_A}-1}$$. Since the weights need to sum to unity, we have

$$w_{\mathrm{n_A}} = 1 - \sum_{i=1}^{\mathrm{n_A}-1} w_i\,.$$

Furthermore, the resulting portfolio's mean return will equal $$\alpha$$ (the constant in the regression), and the portfolio's variance will equal the variance of the residuals.

## choose 1st asset as regressand
y <- mData[ , 1L]

## compute minus excess returns
X <- mData[ , 1L] - mData[ , 2:nA]

## run regression
solR <- lm(y ~ X)


The results should be the same as the results from quadprog:

cat("weights from qp\n")
as.vector(solQP$solution) cat("\nweights from regression\n") as.vector(c(1 - sum(coef(solR)[-1L]), coef(solR)[-1L])) cat("\ncheck: variance of portfolio same as variance of residuals?\n") all.equal(as.numeric(var(mData %*% solQP$solution)), var(solR\$residuals))

weights from qp
[1] 0.07853404 0.12853164 0.14526751 0.09211099 0.11893845
[6] 0.15176486 0.12447023 0.02945822 0.06584904 0.06507502

weights from regression
[1] 0.07853404 0.12853164 0.14526751 0.09211099 0.11893845
[6] 0.15176486 0.12447023 0.02945822 0.06584904 0.06507502

check: variance of portfolio same as variance of residuals?
[1] TRUE


## 4 Solving a system of linear equations

The weights can also be found by solving a system of linear equations.

x <- solve(cov(mData), numeric(nA) + 1)
x <- x / sum(x) ## rescale so that sum(w) is 1
x

[1] 0.07853404 0.12853164 0.14526751 0.09211099 0.11893845
[6] 0.15176486 0.12447023 0.02945822 0.06584904 0.06507502


## 5 References

• Gilli, M., Maringer, D., Schumann, E. (2011) . Numerical Methods and Optimization in Finance. Elsevier/Academic Press. http://nmof.net
• Kempf, A. and C. Memmel (2006). Estimating the Global Minimum Variance Portfolio. Schmalenbach Business Review 58, 332-348.
• R Development Core Team (2008). R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing. http://www.r-project.org.
• Turlach, B.A. [S original] and A. Weingessel [R port] (2007). quadprog: Functions to solve Quadratic Programming Problems. R package version 1.4-11. available from CRAN.