9
votes

I am trying to use solve.QP to solve a portfolio optimization problem (quadratic problem)

Total 3 assets

There are 4 constraints:

  1. sum of weights equal to 1
  2. portfolio expected return equals to 5.2%
  3. each asset weight greater than 0
  4. each asset weight smaller than .5

Dmat is the covariance matrix

Dmat <- matrix(c(356.25808, 12.31581, 261.8830, 212.31581, 27.24840, 18.50515, 261.88302, 18.50515,535.45960), nrow=3, ncol=3)

dvec is each asset's expected return

dvec <- matrix(c(9.33, 3.33, 9.07), nrow=3, ncol=1)

Amat is the constraint matrix

A.Equality <- matrix(c(1,1,1), ncol=1)
Amat <- cbind(A.Equality, dvec, diag(3), -diag(3))

constraint A^T b >= b_0, b vector

bvec <- c(1, 5.2, rep(0, 3), rep(-0.5, 3))

meq=2, since there are two equality constraints, first and second constraints are equality

Then I run the function solve.QP

library(quadprog)
qp <- solve.QP(Dmat, dvec, Amat, bvec, meq=2)

But it gives the error

Error in solve.QP(Dmat, dvec, Amat, bvec, meq = 2) : constraints are inconsistent, no solution!

I am not sure where I did wrong.

1

1 Answers

11
votes

There were two issues with the code you posted:

  • The posted Dmat is not actually symmetric; you had accidentally included value 212.31581 instead of 12.31581
  • The meq=2 option means your first two constraints are held at equality, meaning your weights sum to 1 and your return is exactly 5.2%. The second constraint is apparently the one causing the infeasibility; it seems there are no valid portfolios that have return exactly equal to 5.2% given your other constraints. Indeed, since no more than half the portfolio can have return 3.33% and the rest must have return of at least 9.07%, the return must be 6.2% or greater. Therefore, you should relax this to a >= constraint by setting meq=1.

Here's the working code:

library(quadprog)
Dmat <- matrix(c(356.25808, 12.31581, 261.88302, 12.31581, 27.24840, 18.50515, 261.88302, 18.50515,535.45960), nrow=3, ncol=3)
dvec <- matrix(c(9.33, 3.33, 9.07), nrow=3, ncol=1)
A.Equality <- matrix(c(1,1,1), ncol=1)
Amat <- cbind(A.Equality, dvec, diag(3), -diag(3))
bvec <- c(1, 5.2, rep(0, 3), rep(-0.5, 3))
qp <- solve.QP(Dmat, dvec, Amat, bvec, meq=1)
qp$solution
# [1] 0.3808733 0.5000000 0.1191267

The optimal solution is actually associated with a 6.3% return.