Сохранить неизвестные значения из функции внутри вектора для последующего использования в оптимизации

#r #optimization #finance #quantitative-finance #stochastic

#r #оптимизация #финансы #количественный-финансы #стохастический

Вопрос:

У меня есть функция потерь вида 1 / N * sum(w_i(market_price-model_price) ^ 2) Я хочу минимизировать заданные четыре неизвестных параметра (лямбда, vbar, eta, rho). Для этого мне сначала нужно сгенерировать цены модели с помощью функции HestonCallClosedForm (написанной Дейлом Робертсом https://github.com/daleroberts/heston/blob/master/heston.r ).

Я хочу сохранить сгенерированные «значения», чтобы позже иметь возможность передать их функции потерь. Я не могу сохранить значения. Я знаю, что они не могут иметь никакого числового значения (пока), но я уверен, что у R есть способ справиться с этим. Мои данные состоят из 2399 наблюдений, это выглядит так

 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
 

мой подход к передаче данных заключается в следующем:

 ####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)
 

где HestonCallClosedForm можно найти по ссылке, приведенной выше, и не включена здесь, чтобы не переполнять документ. Функция работает нормально, если введены все параметры, но я не могу указать R использовать неизвестные. Я всегда получаю объект ошибки «par1» не найден.

Комментарии:

1. Я думаю, что ваш вопрос несколько неясен, потому что вы определяете функцию потерь, но не используете ее при оптимизации. Таким образом, в соответствии с предоставленным вами кодом воспроизвести вашу ошибку невозможно.

Ответ №1:

Ваша целевая функция должна принимать в качестве входных данных вектор параметров модели и рыночные цены. Затем он вычисляет цены Хестона с заданными параметрами, сравнивает эти цены модели с рыночными ценами и возвращает единственное число (скажем, среднеквадратичную ошибку).

Затем задача optim состоит в том, чтобы пройти через пространство параметров и найти оптимальные значения для этих параметров, то есть значения, которые делают среднеквадратичную ошибку небольшой. То есть вам нужно передать свою целевую функцию optim .

Комментарии:

1. когда я перехожу loss_function к optim, он сообщает мне, что целевая функция в optim вычисляется до длины 2399 вместо 1. Я понимаю, что означает ошибка, например, проблема, но не способ ее решения

2. Где-то в функции, которую вы вычисляете diff^2 . Вероятно, вам нужно суммировать эти квадраты различий.

3. это то, что я делаю, я просто также присваиваю вес перед diff_sq_w вводом, а затем суммирую

4. Вы говорите return(y) в цикле, поэтому функция никогда не достигает sum , но всегда вычисляет y .