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 :
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!
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With