0

I have a loss function of the form 1/N * sum(w_i(market_price-model_price)^2) I want to minimize given four unknown parameters (lambda, vbar, eta, rho). For that I first need to generate model prices with the function HestonCallClosedForm (written by Dale Roberts https://github.com/daleroberts/heston/blob/master/heston.r).

I want to store the generated "values" to later be able to give it to the loss function. I fail at storing the values. I'm aware that they can't have any numerical value (yet) but I'm sure that R has a way of dealing with this. My data consists of 2399 observations, it looks like this

index_level strike  T mid_price riskfree_rate
1     2826.15   2775 16     68.35        2.3825
2     2826.15   2780 16     64.60        2.3825
3     2826.15   2785 16     60.85        2.3825
4     2826.15   2790 16     57.25        2.3825
5     2826.15   2795 16     53.75        2.3825
6     2826.15   2800 16     50.30        2.3825

my approach of passing the data is the following:

####calibrating the Heston model

S_t <- calibration_file$index_level
K_t <- calibration_file$strike
tau_t <- calibration_file$T
r_t <- calibration_file$riskfree_rate
r_t <- as.numeric(r) #risk free interest rate
q_t <- 0 #dividend rate

x0 <- c(3.00, 0.05, 0.32, -0.85) #initial parameters (lambda, vbar, eta, rho)
lb <- c(1, 0.01, 0.01, -1) #lower bound
ub <- c(10, 1, 1, -0.2) #upper bound


market_price <- calibration_file$mid_price #market price

wi <- 1/market_price #weight

### getting model prices

loss_function <- function(par) {
  par1 <- par[1]
  par2 <- par[2]
  par3 <- par[3]
  par4 <- par[4]
  y <- vector(mode="double", length=length(market_price))
  e <- vector(mode="double", length=length(market_price))
  w <- vector(mode="double", length=length(market_price))
  model_prices <- for(i in 1:6) {
    y[i] <<- HestonCallClosedForm(lambda=par1, vbar=par2, eta=par3,
                                  rho=par4, v0=0.06, r=r_t[i],
                                  tau=tau_t[i], S=S_t[i], K=K_t[i])
    return(y)
  }
  diff <<- market_price - y
  diff_sq <- for(i in 1:6) {
    e[i] <<- diff^2
  }
  diff_sq_w <- for (i in 1:6) {
    w[i] <<- wi[i]*e[i]
  }
  error <<- 1/6 * sum(w)
  return(error)
}


### minimize
par_est <- optim(x0, loss_function, method = "L-BFGS-B", upper = ub, lower = lb)

where HestonCallClosedForm can be found with the link provided above and is not included here to not overcrowd the document. The function works fine if all parameters are inputted but I fail at telling R to use unknowns. I always get the error object "par1" not found.

rubwoer
  • 15
  • 3
  • I think your question is somewhat unclear because you define a loss function but do not use it in your optimization. So according to the code you provided it is not possible to reproduce your error. – mikeHoncho Dec 15 '20 at 09:40

1 Answers1

1

Your objective function needs to take as inputs a vector of model parameters and the market prices. It then computes the Heston prices with the given parameters, compares those model prices to the market prices, and returns a single number (the average squared error, say).

It is then the job of optim to go through the space of parameters and find the optimal values for those parameters, i.e. values that make the average squared error small. That is, you need to pass your objective function to optim.

Enrico Schumann
  • 1,278
  • 7
  • 8
  • when i pass `loss_function` to optim it tells me that the objective function in `optim` evaluates to length 2399 instead of 1. I get what the error means e.g. the issue but not how to solve it – rubwoer Dec 15 '20 at 10:11
  • Somewhere in the function you compute `diff^2`. You probbably need to sum over those squared differences. – Enrico Schumann Dec 15 '20 at 11:07
  • this is what I do I just also assign the weight before in `diff_sq_w` and then sum – rubwoer Dec 16 '20 at 10:42
  • You say `return(y)` in the loop, so the function never reaches `sum`, but always evaluates to `y`. – Enrico Schumann Dec 16 '20 at 14:50