0

I need to find a minimum of an objective function by optimising a vector. The problem is finance related if that helps - the function RC (provided below) computes the sum of squared differences of risk contribution of different assets, where the risk contribution is a product of input Risk Measure (RM, given) and weights.

The goal is to find such weights that the sum is zero, i.e. all assets have equal risk contributions.

RC = function (RM, w){
 
  w = w/sum(w) # normalizing weights so they sum up to 1
  nAssets = length(RM)

  rc_matrix = matrix(nrow=1,ncol=nAssets)
  
  rc_matrix = RM*w #risk contributions: RM (risk measure multiplied by asset's
  #w eight in the portfolio)
  
  rc_sum_squares = numeric(length=1) #placeholder
  
  rc_sum_squares = sum(combn(
          seq_along(RM),
          2,
          FUN = function(x)
            (rc_matrix[ , x[1]] - rc_matrix[, x[2]]) ** 2
        )) # this function sums the squared differences of the risk contributions
  
  return(rc_sum_squares)
}

I searched and the solution seems to lie in the "optim" function, so I tried:


out <- optim(
  par     = rep(1 / length(RM), length(RM)),  # initial guess
             fn      = RC,
             RM      = RM,
             method  = "L-BFGS-B",
             lower   = 0.00001,
             upper   = 1)

However, this returns an error message: "Error in rc_matrix[, x[1]] : incorrect number of dimensions"

I don't know how the optimization algorithm works, so I can't really wrap my head around it. The RC function works though, here is a sample for replicability:

RM <- c(0.06006928, 0.06823795, 0.05716360, 0.08363529, 0.06491009, 0.06673174, 0.03103578, 0.05741140)

w <- matrix(0.125, nrow=1, ncol=1)

I saw also CVXR package, which crashes my RStudio for some reason and nlm(), which is little more complicated and I can't write the function properly.

A solution might be not to do the funky summation of the squared differences, but finding the weights so that the risk contributions (RM*weight) are equal. I will be very glad for your help.

Note: the vector of the weights has to sum up to 1 and the values have to lie between 0 and 1.

Cheers Daniel

  • The code does not pass w to RC. Also the purported reproducible example in the last chunk doesn't provide a complete reproducible piece of code. It just defines two objects but does not call anything with them. – G. Grothendieck Nov 29 '21 at 18:30
  • You have 1 weitght for all the RM array? Or you should have one weight per element in RM array? – RobertoT Nov 29 '21 at 18:31
  • @G.Grothendieck where does the code not pass w to RC? If you mean in the optim() function, I though the left out variable is the one to optimize for. If you mean in the last chunk, you just call RC(RM,w) to see the objective function works. – Luca Pacioli Nov 29 '21 at 19:51
  • @RobertoT the weight array is just an example to test out the RC() function to demonstrate it works. The result of the optimization should be an array of (in this case 8) distinct weights. – Luca Pacioli Nov 29 '21 at 19:53
  • optim works with the first argument of the function. If you want to pass w as a fixed value add it as an argument to optim. optim(par, RC, w = w, ...etc...) where w is already defined. If w is to be optimized as well as RM then RM and w need to be combined into a single variable. – G. Grothendieck Nov 29 '21 at 19:55
  • You should provide a code that we can replicate. There seems to be an error in the function "RC" – Emmanuel Hamel Oct 06 '22 at 21:41

0 Answers0