Search code examples
roptimizationportfolioquadratic-programmingr-portfolioanalytics

R solve.QP tracking error minimization constraints inconsistent


I am struggling with Solve.QP to get a solution to minimize tracking error. I have a benchmark consisting of 6 assets (asset_a to asset_f). For my portfolio I have upper and lower bounds (I cannot have a position in asset_f). The cov matrix is also given. I want to get the portfolio weights for the 6 assets that minimizes tracking error vs the benchmark (with position in asset_f equal to zero).

benchmark:

  1. asset_a: 0.3
  2. asset_b: 0.3
  3. asset_c: 0.1
  4. asset_d: 0.1
  5. asset_e: 0.1
  6. asset_f: 0.1

lowerbounds:

  1. asset_a: 0.166
  2. asset_b: 0.133
  3. asset_c: 0.037
  4. asset_d: 0.035
  5. asset_e: 0.039
  6. asset_f: 0

upperbounds:

  1. asset_a: 1
  2. asset_b: 1
  3. asset_c: 1
  4. asset_d: 1
  5. asset_e: 1
  6. asset_f: 0

benchmark weights and bounds:

test.benchmark_weights = c(0.3, 0.3, 0.1, 0.1, 0.1, 0.1)
test.lowerbound = c(0.166, 0.133, 0.037, 0.035, 0.039,0)
test.upperbound = c(1, 1, 1, 1, 1, 0)

cov matrix (test.Dmat):

test.dmat = matrix(c(0.0119127162,  0.010862842,    0.010266683,    0.0009550136,   0.008242322,    0.00964462, 0.0108628421,   0.010603072,    0.009872992,    0.0011019412,   0.007422522,    0.0092528873,   0.0102666826,   0.009872992,    0.010487808,    0.0012107665,   0.006489204,    0.0096216627,   0.0009550136,   0.001101941,    0.001210766,    0.0115527788,   0.001181745,    0.0008387247,   0.0082423222,   0.007422522,    0.006489204,    0.0011817453,   0.012920482,    0.005973886,    0.00964462, 0.009252887,    0.009621663,    0.0008387247,   0.005973886,    0.0089904809), nrow=6, ncol=6)

dvec (test.dvec):

test.dvec = matrix(c(0, 0,  0,  0,  0,  0), nrow=6, ncol=1)

Amat constraints matrix (test.Amat):

test.amat = matrix(c(1,1,1,1,1,1, 1,1,1,1,1,0, -1,0,0,0,0,0, 0,-1,0,0,0,0, 0,0,-1,0,0,0, 0,0,0,-1,0,0, 0,0,0,0,-1,0, 0,0,0,0,0,-1, 1,0,0,0,0,0, 0,1,0,0,0,0, 0,0,1,0,0,0, 0,0,0,1,0,0, 0,0,0,0,1,0, 0,0,0,0,0,0, -1,0,0,0,0,0, 0,-1,0,0,0,0, 0,0,-1,0,0,0, 0,0,0,-1,0,0, 0,0,0,0,-1,0, 0,0,0,0,0,0), nrow=6, ncol=20)

bvec (test.bvec)

test.bvec =cbind(0, 1, t(test.benchmark_weights), t(test.lowerbound), -t(test.upperbound)) %>% as.matrix() 

then running the solver

solve.QP(as.matrix(test.Dmat), test.dvec, test.Amat, test.bvec)

gives me

constraints are inconsistent, no solution!


Solution

  • Seems like there is something wrong with your Amat and bvec, i.e. you need not have to pass in both sum of weights on first 5 assets equal to 1 and sum of 6 assets equal 1 and also benchmark weights are not constraints but the bounds are:

    library(quadprog)
    N = 6L
    test.dvec = rep(0, N)
    test.amat = cbind(
        rep(1, N),
        diag(1, N),
        diag(-1, N))
    test.bvec = c(1, test.lowerbound, -test.upperbound) 
    
    res = solve.QP(test.dmat, test.dvec, test.amat, test.bvec, meq=1L)
    round(res$solution, 2)
    #[1] 0.17 0.13 0.10 0.44 0.17 0.00