Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mean variance optimisation

I am doing a mean variance optimization to solve portfolios optimization problem. What I am trying to do is to minimize the variance with respect both constraints :

  1. x1m1+x2m2+...+xnmn=m
  2. x1+x2+...+xn=1

So this is the code I did:

################ Simulation for n=3 ################
################ Parameters ################
mu<-50  ## Mean of the portfolio
n<-3    ## Number of asset
m1<-30000  ## Size of the simulation
########### 3 Assets ############
x<- rnorm(m1,2,1)
y<- rnorm(m1,0.5,1.5)
z<- rnorm(m1,3.75,1)
d<-data.frame(x,y,z)

################ Solution Directe  ################
Sol<-function(m1) {
A = matrix(nrow=n+2, ncol=n+2)
    for (i in 1:n){
    for (j in 1:n)
        if(i==j) {
              A[i,j] <-  (2*var(d[,i]))
                } else { 
              A[i,j] <-  cov(d[,i],d[,j]) 
    }
    }

   for (i in 1:n){
             A[i,n+1] <-  -mean(d[,i])   
             A[i,n+2] <-  -1     
    }
   for (j in 1:n){
             A[n+1,j] <-  mean(d[,j])  
             A[n+2,j] <-   1    
    }

  for (i in 2:n+2){
    for (j in 2:n+2)
        if(i==j) {
              A[i,j] <-  0   
                } else { 
              A[i,j] <-  0  
    }
    }
A
Inv=solve(A)
Sol=Inv%*%c(0,0,0,m1,1)
result=list(x=Sol,A=A,Inv=Inv)
return(result) 
}
Sol(mu)
Sol(mu)$x  ## The solution 
Sol(mu)$A

I known, I´m using a lot of bad things for R, but I could not figure out a better solution. So my question is it correct?

Any correction and suggestion to improve this process! please feel free to share your extant code in R.

Huge thanks!

like image 512
Laura Esly Avatar asked Oct 19 '22 19:10

Laura Esly


1 Answers

One way is to minimize numerically by solnp() from the Rsolnp package. This also offers a way to add more restrictions (leverage constraints etc):

muVec <- colMeans(d) #mean-vector of assets
Sigma <- cov(d) #covariance-matrix
fmin <- function(x) as.numeric(t(x) %*% Sigma %*% x) #variance of portfolio to min.
eqn <- function(x) c(t(x) %*% muVec, sum(x)) #equality restriction
sol <- function(mu) Rsolnp::solnp(rep(0.5, 3), fun=fmin, eqfun=eqn, eqB=c(mu,1))
x <- sol(50)

after solving we can now print the parameters and portfolio variance:

> x$par
[1]  -5.490106 -11.270906  17.761012
> x$vscale[1]
[1] 630.4916

In your simple case a closed solution exists and can be boiled down to:

S <- solve(Sigma)
A <- matrix( c(t(muVec) %*% S %*% muVec, 
    rep( t(muVec) %*% S %*% rep(1,3), 2),
    t(rep(1,3)) %*% S %*% rep(1,3)), ncol=2
)
sol2 <- function(mu) S %*% cbind(muVec,1) %*% solve(A) %*% c(mu,1)

which "luckily" gives the same results:

> sol2(50)
        [,1]
x  -5.490106
y -11.270906
z  17.761012
> fmin(sol2(50))
[1] 630.4916
like image 139
J.R. Avatar answered Oct 27 '22 18:10

J.R.