How to compute the tangency portfolio


Enrico Schumann


portfolio optimisation

Review Status



The tangency portfolio is the portfolio that maximises the Sharpe ratio, ie, it is obtained from

\begin{split} \max_{w} \frac{\mu'w-r_f}{\sqrt{w' \Sigma w}}\\ w'\iota = 1 \end{split}

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. The vector $\mu$ holds the assets' means, $$r_f$$ is the riskfree rate (assumed to be a constant). There are no further constraints on the problem, in particular, short sales are allowed here.

The optimisation makes sense only if there exists at least ones portfolio for which $\mu'w$ is larger than $r_f$; otherwise, excess return is negative and no one would want to hold risky assets.

Using a QP solver


We use the quadprog package for R (see the references below).


# create artifical data
nO     <- 100     # number of observations
nA     <- 10      # number of assets
mData  <- array(rnorm(nO * nA, mean = 0.001, sd = 0.01), dim = c(nO, nA))
rf     <- 0.0001     # riskfree rate (2.5% pa)
mu     <- apply(mData, 2, mean)    # means
mu2    <- mu - rf                  # excess means

# qp
aMat  <- as.matrix(mu2)
bVec  <- 1
zeros <- array(0, dim = c(nA,1))
solQP <- solve.QP(cov(mData), zeros, aMat, bVec, meq = 1)

# rescale variables to obtain weights
w <- as.matrix(solQP$solution/sum(solQP$solution))

# compute sharpe ratio
SR <- t(w) %*% mu2 / sqrt(t(w) %*% cov(mData) %*% w)

A regression representation

Britten-Jones [1] showed that the same results can be obtained by running the following regression

\begin{align} 1 = Xw + \varepsilon\,. \end{align}

Here $1$ is a vector of ones, $X$ holds in its columns the excess returns of the assets (each row is one observation), and $\varepsilon$ holds the remaining errors.

The obtained regression weights need to be rescaled, ie,

\begin{align} w_i = \frac{w_i}{\sum w} \quad \text{for all $i$}\,. \end{align}


# (...continued)

# regression

# compute excess returns
X     <- mData - rf
ones     <- array(1, dim = c(100,1))

# run regression
solR     <- lm(ones~-1 + X)

# rescale 
w2 <- coef(solR)
w2 <- w2/sum(w2)

Solving a system of linear equations

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


# (...continued)

# solve
w3 <- solve(cov(mData),mu2)

# rescale
w3 <- w3/sum(w3)

All three methods should give the same results:

# (...continued)


# regression

# linear equations

# check

Internal Links

How to compute the global minimum-variance portfolio
Related Articles

External links

1. Britten-Jones, M. (1999). The Sampling Error in Estimates of Mean-Variance Efficient Portfolio Weights. Journal of Finance 64, 655-671.
2. Gilli, M., D. Maringer and E. Schumann. (2011). Numerical Methods and Optimization in Finance. Elsevier.
3. R Development Core Team (2008). R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing.
4. 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.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License