OK, had a look at the data, and it's OK. The problem is, as the error says, that the covariance matrix is not a positive definite. A quick test confirms that (BTW - I'm using packages matrixcalc and Matrix):
library(tseries) prices <- read.csv2("20153Q.csv",header=TRUE,dec=".") n <- nrow(prices) returns <- (prices[2:n,])/(prices[1:(n-1),])-1 portfolio.optim(as.matrix(returns), shorts=FALSE,riskless=FALSE) # cov(X) not a positive definitive # check matrixcalc::is.positive.definite(cov(returns)) gets
> matrixcalc::is.positive.definite(cov(returns)) [1] FALSE What you can do is adjust the covariance matrix to its nearest positive definite matrix by using Matrix::nearPD
returns.nearest.PD <- Matrix::nearPD(cov(returns))$mat returns.nearest.PD <- as.matrix(returns.nearest.PD) which will then allow you to using portfolio.optim by explicitly specifying the covmat:
(po <- portfolio.optim(as.matrix(returns), covmat = returns.nearest.PD, shorts=FALSE,riskless=FALSE)) which works without error:
> sum(po$pw) [1] 1 and you can confirm that it has weights for each symbol:
> length(po$pw) [1] 99 EDIT Just to be sure, the adjusted covariance matrix is very close to the original covariance matrix, the diffs are miniscule:
> # the matrices are really close > sum((abs(returns.nearest.PD - cov(returns)) > 0.000000001)==TRUE) [1] 0 > # the matrices are really close > sum((abs(returns.nearest.PD - cov(returns)) > 0.0000000001)==TRUE) [1] 74