Проблема в оптимизации / калибровке в R с использованием различных алгоритмов
Я новичок в оптимизации / калибровке, поэтому я хочу объяснить каждую деталь этого. Так что это будет очень длинный пост, будьте добры ко мне:)
Я пытался откалибровать модель Heston (1993) для цен опциона, используя высокочастотные данные. Но я сталкиваюсь с определенными проблемами.
У меня есть 5 параметров для оценки (каппа, тета, сигма, ро, v0). Ниже приведен подход, которому я следую:
Вычислить (угадать) начальное значение параметров для ввода в алгоритм оптимизации. Я сделал это методом проб и ошибок.
Использовать
callHestoncf
изNMOF
пакет для расчета цены опциона.Рассчитайте разницу рыночной цены опционов и цен, рассчитанных по (2)
Разница, полученная из (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. Наконец, что я должен сделать, чтобы сделать эту работу:)
Спасибо за терпение до конца. Даже после нескольких дней я не могу найти путь вперед. Было бы здорово, если бы кто-нибудь мог мне помочь с этим.
Спасибо и С уважением,
Шивам