# R package for portfolio

In the context of modern portfolio theory, one often wishes to minimise $\mathbf{w}^{\mathrm{{\scriptstyle T}}}\boldsymbol{\Sigma}\mathbf{w}$ subject to $\mathbf{w}^{T}\boldsymbol{\mu}=c_{1}$, $\left\Vert \mathbf{w}\right\Vert _{1}<c_{2}$ and $\mathbf{w}^{T}\mathbf{1}=1$. Is there an R function or package to do this?

If you can add linear constriants (as you can do in quadprog) then you can formulate $w \mu = c_1$ as linear constraint, no matter what $\mu$ is (and first delete it from the objective by setting the parameter to zero. The only problem is the one norm. Let my clarify, this is: $$\sum_{i=1}^n |w_i| < c_2$$ Thus you allow for short sales but you want to limit leverage -> right? I am afraid that quadprog can not handle such constraints.

Some solvers can handle quadratic constraints then $$\sum_{i=1}^n |w_i|^2 = w^T w< c_2^*$$ would limit leverage. The first equation above describes a constraint for the $L_1$-norm. If you mean that $|w_i|$ should be bounded for each $i$ then of course you get this by the two inequalities: $$w \le c_2 \quad \text{and} \quad w \ge -c_2.$$

EDIT after the comment of John: THe package nloptr can handle non-linear constraints. Follow the examples in the link to define the objective function and the constraint. Note that the gradient of $$f(w) = w^T \Sigma w$$ is given by $$2 \Sigma w.$$ Providing the gradient will improve the result of this non-linear optimizer.

EDIT: If you want something built for portfolio optimization directly then you could look at fPorfolio and e.g. this presentaton. I find that the documentation lacks details and I wonder whether all features "promised" in the presentation work properly. On page 13 they say that the package can handle non-linear constraints. If you try it then please tell us whether this works.

• Good answer. nloptr would allow either an L1-norm or an L2-norm.
– John
Commented May 20, 2015 at 15:29
• Yes, @Richard, you are correct that quadprog won't work. Can you recommend any alternative packages? Commented May 21, 2015 at 10:37
• I edited and took into account the comment of John about the package nloptr. Commented May 21, 2015 at 11:20
• @Richard -- thank you for the suggestion to use nloptr. I'll certainly give it a go. But is there not something more suited for a qudratic programming setup (with non linear constraints) as opposed to using a generic optimisation package? I've had experience with these things before... and they often either fail to converge or end up at local optima. Either way, thank you for input it's greatly appreciated. Commented May 21, 2015 at 11:52
• You could have a closer look at fPortfolio but I don't know whether everything that they promised really works. Commented May 21, 2015 at 12:28

I wonder if it's possible to use solve.QP from quadprog by using dummy variables. One dummy variable $y_i$ would be used for each $w_i$, each $y_i$ would be constrained to be greater than zero, and the leverage constraint would be applied to the sum of the $y_i$. Problem formulation would look like $$\text{min } w^tΣw$$ subject to the constraints $$w^t\mu= c_1$$ $$w^t 1 = 1$$

$$y_i \geq 0$$ $$w_i + y_i \geq 0$$ $$-w_i + y_i \geq 0$$

$$-\sum y_i \geq -c_2$$

Code could look like

leveraged_port <- function( er,cov.mat, target_return=NULL, leverage=1., tickers=NULL ){
if(leverage < 1.) stop( "leverage must be >= 1.")
if( target_return > (leverage+1)/2*max(er)) stop("target_return not achievable; increase leverage or decrease target_return")
n_asset <- length(er)
zeros <- integer(n_asset)
# calculate small diag value for dummy variables so Dmat is positive def.
diag_dum <- 1.e-05*min(diag(cov.mat))
Dmat <- diag(diag_dum, nrow=2*n_asset, ncol=2*n_asset)
Dmat[1:n_asset, 1:n_asset] <- 2*cov.mat
dvec <- numeric(2*n_asset)
meq <-  2
# constraints on weights
bvec <- c(1, target_return)
Amat <- matrix( c(rep(1,n_asset), er, diag(n_asset), -diag(n_asset), diag(0, nrow=n_asset),
zeros), nrow=n_asset)
# constraints on dummy variables
bvec <- c(bvec, zeros, zeros, zeros, -leverage)
Amat <- rbind( Amat, matrix(c(zeros, zeros, diag(n_asset), diag(n_asset), diag(n_asset),
-rep(1,n_asset)), nrow=n_asset))
sol<-solve.QP(Dmat, dvec, Amat, bvec, meq=meq)
weights<-sol$solution[1:n_asset] names(weights) <- tickers exp.ret <- t(er)%*%weights std.dev <- sqrt(weights %*% cov.mat %*% weights) ret <- list(er = as.vector(exp.ret), StdDev = as.vector(std.dev), weights = weights, sum_weights = sum(weights), leverage = sum(abs(weights)), lagrange_mults=sol$Lagrangian )
}


Results on the following example problem seem feasible

library(quantmod)
tickers <- c("MSFT","AAPL", "AMZN", "YHOO", "XOM", "CVX", "UNH", "NKE")
prices <- do.call(cbind,
lapply(tickers, function(x) getSymbols(x, from="2010-01-01", auto.assign=FALSE, warnings=FALSE)[,6]))
colnames(prices) <- tickers
returns <- diff(prices, arithmetic=FALSE, na.pad=FALSE) - 1
means <- sapply(returns, mean)

QPsol <- leveraged_port(er=means, cov.mat=cov(coredata(returns)), target_return=.0016, leverage=1.8, tickers)


with the results

QPsol
$er [1] 0.0016$StdDev
[1] 0.01830004

$weights MSFT AAPL AMZN YHOO XOM CVX UNH NKE -9.809695e-14 1.044254e+00 -5.297152e-14 -1.780017e-17 -4.000000e-01 -1.556950e-13 3.557464e-01 4.224909e-14$sum_weights
[1] 1

$leverage [1] 1.8  • This is a very clever solution. Commented May 26, 2015 at 11:03 • Really very clever! In short$y_i = |w_i|$-> right? Commented May 26, 2015 at 12:05 • @Richard exactly. Absolutely excellent. Commented May 26, 2015 at 12:57 • Auxiliary variables can be tricky though when you extend them to other circumstances, like turnover constraints or transaction costs. You sometimes have to impose additional constraints to ensure that$w_{i}y_{i}=0\$, which makes the problem no longer fit for quadratic optimizers.
– John
Commented May 26, 2015 at 18:19