I have time-series data for N stocks.
sample.data<-replicate(10,rnorm(1000))
, where each column shows the returns of different stocks over time.
I am trying to construct a portfolio weight vector to minimize the variance of the returns.
the objective function:
min w^{T}\sum w
s.t. e_{n}^{T}w=1
\left \| w \right \|\leq C
where w is the vector of weights, \sum
is the covariance matrix, e_{n}^{T}
is a vector of ones, C
is a constant. Where the second constraint (\left \| w \right \|
) is an inequality constraint.
I used the following code to solve this problem:
library(Rsolnp)
gamma<-1
fn<-function(x) {cov.Rt<-cov(sample.data); return(t(x)%*%cov.Rt%*%x)} #OBJECTIVE FUNCTION TO MINIMIZE
eqn<-function(x){one.vec<-matrix(1,ncol=10,nrow=1); return(one.vec%*%x)} #EQUALITY CONSTRAINT
constraints<-1 #EQUALITY CONSTRAINT
ineq<-function(x){one.vec<-matrix(1,ncol=10,nrow=1); #INEQUALITY CONSTRAINT
z1<-one.vec%*%abs(x)
return(z1)
}
uh<-gamma #UPPER BOUND
lb<-0 #LOWER BOUND
x0<-matrix(0,10,1) #STARTING PARAMETER VECTOR (NOT SURE WHAT STARTING VALUES TO PUT HERE)
sol1<-solnp(x0,fun=fn,eqfun=eqn,eqB=constraints, ineqfun=ineq,ineqUB=gamma,ineqLB=lb)
When running this code I get the following error message:
Error in solve.default(cz,tol = 1e-25) : system is computationally singular: reciprocal condition number = 0 In addition: There were 50 warnings (use warnings() to see the first 50)
warnings()
1: In cbind(temp, funv): number of rows of result is not a multiple of vector length
Any ideas what I might be doing wrong?
Is there a problem with the starting parameter vector x0
?
I changed your code slightly:
When we run the above code we get a solution of:
But when we add the inequality restriction to the optimization problem, then we run into problems:
Let's try to change gamma just a little:
gamma <- 1.01
So your inequality constraint seems to be binding exactly around the equality constraint. Also looking at the two constraints together, it seems a little strange to me. My guess is, that you probably specified your inequality constraint wrong and simply wants something like a shortselling constraint, eg. weights between 0 and 1. This could be archieved following your method by: