4

I am new to using R and portfolio optimization. I am trying to optimize a portfolio with 7 assets such that asset number 3 and 4 have a minimum weight of 0.35 each and the sum of all 7 assets equal to 1. Following is the code I have tried:

library(quadprog)
dmat <- cov(dr) #dr stores the daily return of the 7 assets and is a timeSeries object
dvec <- colMeans(dr)
c1 <- c(0,0,1,0,0,0,0)
c2 <-  c(0,0,0,1,0,0,0)
amat <- t(rbind(matrix(1, ncol = ncol(dmat)), c1, c2)) #used transpose because earlier when I didn't use the transpose I got an error saying amat and dvec are not compatible
bvec <- matrix(c(1,0.35, 0.35), nrow =3)
meq <- 1
sol <- solve.QP(dmat, dvec, amat, bvec, meq)

Here is the answer that I get from the above code:

$solution
[1] -0.01619018 -2.10640140  0.35000000  0.35000000 -0.82522310  1.27499728  1.97281741

$value
[1] -0.0007364101

$unconstrained.solution
[1]  0.026872891 12.595238193 -0.256430652  0.008918392  0.743618974  2.212816019  3.749097189

$iterations
[1] 4 0

$Lagrangian
[1] 0.0002874682 0.0002846590 0.0003015167

$iact
[1] 1 3 2

Since the solution has weights for 2 assets in excess of 1, I must have made a mistake in the Amat or bvec or meq. However, I am unable to figure out what is that mistake.

Could someone guide me on how to construct those matrices to tackle this problem? Thanks in advance for any help.

Alok
  • 43
  • 1
  • 4

1 Answers1

2

Your answer sums to one but what allowed some of the weights to be greater than one is that you did not restrict your weights to be positive. If that's what you want, you need to add one constraint per variable. This works:

dr <- matrix(runif(100*7), 100, 7) # made up data for this example
n <- ncol(dmat)
dmat <- cov(dr)
dvec <- colMeans(dr)
c1 <- c(0,0,1,0,0,0,0)
c2 <-  c(0,0,0,1,0,0,0)
amat <- t(rbind(matrix(1, ncol = n), c1, c2, diag(n)))
bvec <- c(1, 0.35, 0.35, rep(0, n))
meq <- 1
solve.QP(dmat, dvec, amat, bvec, meq)
# $solution
# [1] 0.0000000  0.0291363  0.3500000  0.4011211  0.0000000
# [6] 0.0000000  0.2197425
# [...]

Following your comments about the possibility to short, it now sounds like your variables should be bounded by -1 and 1. Then use:

amat <- t(rbind(matrix(1, ncol = n), c1, c2, diag(n), -diag(n)))
bvec <- c(1, 0.35, 0.35, rep(-1, n), -rep(1, n))
solve.QP(dmat, dvec, amat, bvec, meq)
# $solution
# [1] -0.51612776  0.30663800  0.35000000  0.54045253 -0.14679397
# [6] 0.02342572  0.44240548
# [...]
flodel
  • 87,577
  • 21
  • 185
  • 223
  • How do I put that restriction? What I am trying to achieve is have asset number 3 and 4 to be at least 0.35, which the overall sum of the 7 assets = 1. I want to allow shorting of assets, so all the other assets would technically have varying weights from -1 to 0.30 (since sum of assets 3 and 4 would be at least 0.70) I am unable to create the constraint matrix for these conditions. – Alok May 15 '13 at 14:15
  • @Alok, please see my updated answer. It should address your new constraints. – flodel May 16 '13 at 00:08
  • Thank you so much. I guess, this gives me the right results. Made a little change in the bvec though. `bvec <- c(1, 0.35, 0.35, rep(-1, n), -0.3, -0.3, -0.35, -0.35, -0.3, -0.3, -0.3)` Thank you again for your help! – Alok May 16 '13 at 04:48