I want to construct my own optimization using R's optimization function.
The objective function is the diversification ratio, to maximize it (hope its correct):
div.ratio<-function(weight,vol,cov.mat){
dr<-(t(weight) %*% vol) / (sqrt(t(weight) %*% cov.mat %*% (weight)))
return(-dr)
}
A example:
rm(list=ls())
require(RCurl)
sit = getURLContent('https://github.com/systematicinvestor/SIT/raw/master/sit.gz', binary=TRUE, followlocation = TRUE, ssl.verifypeer = FALSE)
con = gzcon(rawConnection(sit, 'rb'))
source(con)
close(con)
load.packages('quantmod')
data <- new.env()
tickers<-spl("VTI,VGK,VWO,GLD,VNQ,TIP,TLT,AGG,LQD")
getSymbols(tickers, src = 'yahoo', from = '1980-01-01', env = data, auto.assign = T)
for(i in ls(data)) data[[i]] = adjustOHLC(data[[i]], use.Adjusted=T)
bt.prep(data, align='remove.na', dates='1990::2013')
prices<-data$prices[,-10] #don't include cash
ret<-na.omit(prices/mlag(prices) - 1)
vol<-apply(ret,2,sd)
cov.mat<-cov(ret)
optimize(div.ratio,
weight,
vol=vol,
cov.mat=cov.mat,
lower=0, #min constraints
upper=1, #max
tol = 0.00001)$minimum
I get the following error message which seems to be it that optimization package doesn't do vector optimization. What did I do wrong?
Error in t(weight) %*% cov.mat : non-conformable arguments
First of all, weight
has no reason to be in the optimize call if that's what you are trying to optimize.
Then, optimize
is for one-dimensional optimization while you are trying to solve for a vector of weights. You could use the optim
function instead.
Regarding your second question in the comments, how do you set a constraint that it sums to 1 for the function? You can use the trick proposed here: How to set parameters' sum to 1 in constrained optimization, i.e, rewrite your objective function as follows:
div.ratio <- function(weight, vol, cov.mat){
weight <- weight / sum(weight)
dr <- (t(weight) %*% vol) / (sqrt(t(weight) %*% cov.mat %*% (weight)))
return(-dr)
}
This gives:
out <- optim(par = rep(1 / length(vol), length(vol)), # initial guess
fn = div.ratio,
vol = vol,
cov.mat = cov.mat,
method = "L-BFGS-B",
lower = 0,
upper = 1)
Your optimal weights:
opt.weights <- out$par / sum(out$par)
# [1] 0.154271776 0.131322307 0.073752360 0.030885856 0.370706931 0.049627627
# [7] 0.055785740 0.126062746 0.007584657
pie(opt.weights, names(vol))
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