Skip to content
All library documents

Long-Only Minimum-Variance Portfolios with a Precision Matrix

Article Quant Q&A · Author: user13895

Summary

The question concerns finding minimum-variance portfolio weights when short sales are prohibited, with a particular focus on using an inverse covariance matrix directly. It presents the usual constraints: weights sum to one, achieve a target expected return, and remain nonnegative. The questioner’s attempt uses unconstrained Lagrange-multiplier weights and then clips negative values to zero.

The answer recommends specifying full-investment and long-only constraints in PortfolioAnalytics and optimizing portfolio risk from the returns matrix. It names ROI and DEoptim as possible optimization methods, and points to examples using a standard-deviation objective. The response does not show how to pass a precision matrix into the optimizer or explain how to handle a non-positive-definite covariance matrix. Its practical advice is therefore to use a constrained portfolio optimization workflow, rather than repair the unconstrained weights by clipping; the specific matrix and optimizer setup may need further investigation.

Key ideas

  • The unconstrained Lagrange solution does not enforce nonnegative weights.
  • Clipping negative weights to zero can violate the portfolio budget and target-return constraints.
  • PortfolioAnalytics can express full-investment and long-only constraints alongside a risk objective.
  • The answer suggests ROI or DEoptim, but does not explain how to optimize directly with a precision matrix.

Tags

Full text
# short-sale constraint with nonpositive-definite matrix in portfolio optimization


# short-sale constraint with nonpositive-definite matrix in portfolio optimization












I need help about portfolio optimization in R. I have inverted matrix and I want to use it as an input in portfolio optimization. It was non-positive definite before I have handled it. In portfolio selection theory we need inverted matrix I have already have it. The problem for me that to impose a non-negativity constraint (short sale prohibited) on weights. In traditional optimization packages we have to put covariance matrix and it solves. I do not want cope with the covariance matrix by using different technique. I have already inverted matrix. The aim for me to solve portfolio selection codes with putting inverted covariance matrix(precision matrix) under non-negativity constraint (each element of weight vector must be positive) Which method should I use I do not know. If you help me, I would be very happy..

This is my work so far:

I am trying to construct a portfolio weight vector to minimize the variance of the returns.

```
       w ̂=argmin w'Σ w
s. t.  w'I = 1           #weights sum up to 1                                                 
       w'μ=ρ             #target expected return
       w≥0               #non-negativity(short-sale) constraint
```

where w is the vector of weights, Σ covariance matrix.

```
optimization<-function(returns) {
  p <- ncol(x)                    #number of assets
  n <- nrow(x)                    #number of observations
  x <- matrix(data$return,n,assets)
  mean <- colMeans(na.rm=FALSE,x)
  M <- as.integer(10)             #nuber of ports on the eff.front.
  S <- cov(x)                     #covariance matrix
  Rmax<- 0.01                     #max monthly return value
  Dmat   <- solve(S)              #inverse of covariance matrix
  u <- rep(1,p)                   #vector of ones

  These codes are for the Lagrange solutions

  a<- matrix(rep(0,4), nrow=2)    
  a[1,1] <- t(u)%*% Dmat %*%u 
  a[1,2] <- t(mean)%*%Dmat%*%u
  a[2,1] <- a[1,2] 
  a[2,2] <- t(mean)%*%Dmat%*%mean 
  d <- a[1,1]*a[2,2]-a[1,2]*a[1,2] 
  f <- (Dmat%*%(a[2,2]*u-a[1,2]*mean))/d 
  g <- (Dmat%*%(-a[1,2]*u+a[1,1]*mean))/d
  r <- seq(0, Rmax, length=M)
  w <- matrix((rep(0, p*M)), nrow=p)
```

I tried to find non-negative weights using the codes below:

```
for(i in 1:M) { w[,i] = f+r[i]*g                    #portfolio weights 
      if (w[,i] <0) {w[,i]=0} else {w[,i]=w[,i]}
    }
```

Also, I tried to make a loop using 'while' function in R.

```
while (w> 0) 
  { for(i in 1:M) { w[,i] = f+r[i]*g }
  print(w)                     
  }
```

Unfortunately, I could not get the positive weights. Is there another solution to get positive weights?

## Answer by Kyle Balkissoon (score 1)

https://quant.stackexchange.com/a/16002

Why not just use PortfolioAnalytics, as if your matrix is non positive definite you will have problems using non optimization approaches.

Here is an example taken from my blog: retmat is a matrix of returns

library(PortfolioAnalytics) moms_portfolio = portfolio.spec(assets=colnames(retmat)) moms_portfolio = add.constraint(portfolio=moms_portfolio,type="full_investment") moms_portfolio = add.constraint(portfolio=moms_portfolio,type="long_only") moms_portfolio = add.objective(portfolio=moms_portfolio,name="StdDev",type="risk")

/#Optimize (May want to switch to DEoptim or different optimizer if ROI fails)

optimal_portfolio = optimize.portfolio(retmat,moms_portfolio,optimize_method="ROI")

optimal_portfolio = optimize.portfolio(retmat,moms_portfolio,optimize_method="DEoptim", search_size=5000, trace=TRUE, traceDE=0)

edit 1: Documentation

see here for general optimization with Portfolio analytics: Portfolio Optimization Vignette

Portfolio Optimization With custom moments and objectives

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.