Background
My final objective is to find a portfolio located on the efficient frontier from a choice of 100 stocks from a stock index (eg. S&P500).
This efficient portfolio will be such that its variance is the same as the stock index variance. Wrapping it up, maximizing return for a given target risk.
Problem
I first learned how to use the PortfolioAnalytics package but I got an error from the function create.efficientFrontier whenever I passed the argument type="mean-StdDev" to the function.
Without a solution for the problem above, I decided to use the fPortfolio package. I got an efficient frontier but I can't get a matrix with the weights, returns and variance together so I can do a binary search on the variance column and then select the corresponding weights (maybe there is a way but I'm new to R).
Without a solution for the problem above, I decided to go straight to the solve.QP solution. I finally was able to do what I wanted in the first place.
Once I got an efficient frontier, I decided to compare it with the one I got from fPortfolio. For my surprise, the variance results differ significantly while returns are the same. Once I troubleshot, I found out that the difference was due to the Dmat argument, ie, the covariance matrix.
I'm passing Dmat <- Cov * 2 to the solve.QP function but if I instead use Dmat <- Cov then I get the same results from fPortfolio. Nothing changed, same dataset, same constraints. Obviously, the variance of the portfolios from solve.QP is twice the variance of those from fPortfolio.
I'm using the most basic default configuration in fPortfolio, i.e., only passing the returns dataset to it.
MV Portfolio Frontier
Estimator: covEstimator
Solver: solveRquadprog
Optimize: minRisk
Constraints: LongOnly
Question
I have come across some codes in the web multiplying the covariance matrix by 2 and passing this as Dmat. Yet, some other codes simply pass the covariance matrix as Dmat to the solve.QP function (i.e, without multiplying it by 2).
- Which approach is correct?
From my investigation of quadratic programming and the solve.QP function, I believe the covariance matrix must be multiplied by 2.
The solve.QP routine implements the dual method of Goldfarb and Idnani (1982, 1983) for solving quadratic programming problems of the form min(-d^T b + 1/2 b^T D b) with the constraints A^T b >= b_0.
The mean-variance optimization (efficient frontier) is a quadratic programming problem of the form min(w^T D w - q R^T w) with the constraints A^T w >= w_0.
Therefore, when translating the MV objective function to the equivalent form used by solve.QP, the covariance matrix must be multiplied by 2.
However, this would imply that the code from fPortfolio is incorrect.
- Has anybody noticed this behavior of fPortfolio before?
I guess I'm missing something very basic in here!
Code
eff.frontier <- function (ret, max.allocation=NULL, rf=0, risk.limit=.5, risk.increment=.005)
{
Dmat <- 2 * cov(ret)
n <- ncol(Dmat)
Amat <- cbind(1, diag(n))
bvec <- c(1, rep(0, n))
meq <- 1
if(!is.null(max.allocation)){
Amat <- cbind(Amat, -diag(n))
bvec <- c(bvec, rep(-max.allocation, n))
}
nLoops <- risk.limit / risk.increment + 1
iLoop <- 1
eff <- matrix(.0, nrow=nLoops, ncol=n+3)
colnames(eff) <- c(colnames(returns), "Return", "StdDev", "SharpeRatio")
for (i in seq(from=0, to=risk.limit, by=risk.increment))
{
dvec <- colMeans(ret) * i
sol <- solve.QP(Dmat=Dmat, dvec=dvec, Amat=Amat, bvec=bvec, meq=meq)
eff[iLoop,"StdDev"] <- sqrt(sum(sol$solution %*% colSums((Dmat * sol$solution))))
eff[iLoop,"Return"] <- as.numeric(sol$solution %*% colMeans(ret))
eff[iLoop,"SharpeRatio"] <- (eff[iLoop,"Return"]-rf) / eff[iLoop,"StdDev"]
eff[iLoop,1:n] <- sol$solution
iLoop <- iLoop+1
}
return(as.data.frame(eff))
}
fPortfolio
? $\endgroup$