Проблема в оптимизации / калибровке в R с использованием различных алгоритмов

Я новичок в оптимизации / калибровке, поэтому я хочу объяснить каждую деталь этого. Так что это будет очень длинный пост, будьте добры ко мне:)

Я пытался откалибровать модель Heston (1993) для цен опциона, используя высокочастотные данные. Но я сталкиваюсь с определенными проблемами.

У меня есть 5 параметров для оценки (каппа, тета, сигма, ро, v0). Ниже приведен подход, которому я следую:

  1. Вычислить (угадать) начальное значение параметров для ввода в алгоритм оптимизации. Я сделал это методом проб и ошибок.

  2. Использовать callHestoncf из NMOF пакет для расчета цены опциона.

  3. Рассчитайте разницу рыночной цены опционов и цен, рассчитанных по (2)

  4. Разница, полученная из (3), вводится в функцию оптимизации.

Ниже приведены данные, которые я использую:

dput (головка (температура))
структура (список (EXPDATE = структура) (c(1296066600, 1296066600, 1296066600, 1296066600, 1296066600, 1296066600), класс = c("POSIXct", "POSIXt")), STRIKE = c(6400L, 6400L, 6400L, 6400L, 6400L, 6400L, 6400L), TTE = с (17, 17, 17, 17, 17, 17), SPOT = с (6146.39759036145, 6146.16962025316, 6148.28617021277, 6147.04015151515, 6140.85952380952, 6139,94405940594), скорость = с (0,0745855265628133, +0,0745855265628133, +0,0745855265628133, +0,0745855265628133, 0,0745855265628133, 0,0745855265628133), DIV = c(0,0101, 0,0101, 0,0101, 0,0101, 0,0101, 0,0101), DATE = c("2011-01-04", "2011-01-04", "2011-01-04", "2011-01-04", "2011-01-04", "2011-01-04"), QUANT = c(2000L, 2400L, 1600L, 2500L, 2000L, 1500L), ЦЕНА = c(16.05, 16, 15.9, 16.4, 15, 15)), .Names = c("EXPDATE", "STRIKE", "TTE", "SPOT", "RATE", "DIV", "DATE", "QUANT", "PRICE"), row.names = c(NA, 6L), class = "data.frame")

А ниже находится функция для расчета цели, которая будет минимизирована:

#callHestoncf <- function(S,X,tau,r,q,v0,vT,rho,k,sigma,implVol = FALSE)
#input = [kappa theta sigma rho v0]
function(initial, df){
    hdiff = rep(0, nrow(df))
    if (2*initial[1]*initial[2]-initial[3]^2<0){    ##condition on parameters
            initial[1]=initial[1]+0.1
            initial[2]=initial[2]+0.05}
    else if (2*initial[1]*initial[2]-initial[3]^2>=0){
            for (i in 1:nrow(df)){
                    hdiff[i] = abs((df['PRICE'][i,] - callHestoncf(df['SPOT'][i,], df['STRIKE'][i,], df['TTE'][i,]/250, df['RATE'][i,], 
                                                                   df['DIV'][i,], initial[5], initial[2], initial[4], initial[1], initial[3])))
            }
            #return(as.numeric(max(hdiff)))
            return(as.numeric(mean(hdiff)))
            #return(as.numeric(hdiff))
    }}

Я использовал следующие функции для оптимизации:
nlminb (статистика)
DEoptim (DEoptim)
optim (статистика) - методы "L-BFGS-B", "SANN"
GenSA (GenSA)

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

calcdiff=function(df, initial2){
    A=rep(0,nrow(df))
for (i in 1:nrow(df)){
    A[i] = abs((df['PRICE'][i,] - callHestoncf(df['SPOT'][i,], df['STRIKE'][i,], df['TTE'][i,]/250, df['RATE'][i,], 
                                               df['DIV'][i,], initial2[5], initial2[2], initial2[4], initial2[1], initial2[3])))

}    
return (A)}

И ниже, как я это называю

initial2=c(0.3131582,0.01,0.2480684,-0.7201562,0.2845104)   ####parameter set obtained after optimization
ans = calcdiff(temp, initial2)
summary(ans)

Ниже показано, как я называю функции оптимизации:

initial = c(0.6, 0.01, 0.15, -0.5, 0.0196)
lb = c(0.01, 0.01, 0.01, -1, 0.01)
ub = c(1, 0.4, 1, 1, 0.4)
soln = nlminb(start=initial,objective=hestdiff,lower=lb, upper=ub, df=temp)

soln = DEoptim(hestdiff,lower=lb, upper=ub, df=temp, DEoptim.control(trace=FALSE, CR=0.7))

soln = optim(par = initial, fn = hestdiff, gr = NULL, method = "SANN", lower = lb, upper = ub, df = temp, control = list(maxit = 30000, trace = TRUE))

soln = optim(par = initial, fn = hestdiff, gr = NULL, method = "L-BFGS-B", lower = lb, upper = ub, df = temp, control = list(trace = 2))

soln=GenSA(par=initial, fn=hestdiff, lower=lb, upper=ub, df=temp,control=list(smooth=FALSE, verbose=TRUE))

Используя функцию nlminbЯ мог бы получить достаточно точную оценку параметров и низкую погрешность ценообразования (среднее = 3,7 рупий, медианное = 3,5 рупий), но, как я понимаю, это локальный подход к оптимизации, поэтому выбор входных данных очень критично Кроме того, так как я должен выполнить эту калибровку в течение многих дней, не очень выполнимо каждый день делать начальные оценки и пробные результаты. Поэтому я искал глобальный оптимизатор.

С помощью DEoptim (с теми же значениями, что и выше): он выполняет 200 итераций и приводит к параметрам: c(0,7239727, 0,01, 0,5224246, 0,9484754, 0,2316809). Используя эти значения, я получаю непомерные ошибки (среднее значение = 211 рупий, среднее значение = 208 рупий).

С помощью L-BFGS-B имеет аналогичные проблемы, как nlminb

Когда я использую SANN или же GenSA, которые являются глобальными оптимизаторами, я получаю ошибку ниже после нескольких итераций

Error in integrate(P2, lower = 0, upper = Inf, S, X, tau, r, q, v0, vT,  : 
  the integral is probably divergent 

Я знаю, что ошибка происходит, потому что интеграл не разрешим для определенных значений в диапазоне параметров. Но не должен ли быть встроенный механизм, чтобы игнорировать такие случаи?
Проблема может быть многократной здесь, хотя я чувствую, что это не из-за пунктов 1-4 ниже:
1. Правильно ли я рассчитываю цель?
2. Возвращаю ли я правильную целевую функцию к алгоритму оптимизации? (функция 'hestdiff' выше)
3. Есть ли проблема в том, как я вычисляю свою цену? (функция 'calcdiff' выше)
4. Есть ли проблема в способе вызова функций оптимизации?
5. Есть ли другие функции оптимизации, которые я могу / должен использовать?
6. Наконец, что я должен сделать, чтобы сделать эту работу:)

Спасибо за терпение до конца. Даже после нескольких дней я не могу найти путь вперед. Было бы здорово, если бы кто-нибудь мог мне помочь с этим.

Спасибо и С уважением,
Шивам

0 ответов

Другие вопросы по тегам