DEoptim не возвращает оптимальные параметры

Я пытаюсь использовать DEoptim для оптимизации параметров модели ценообразования Heston (пакет NMOF). Моя цель — свести к минимуму разницу между реальной ценой опциона и ценой хестон. Однако при запуске моего кода DEoptim не сохраняет лучший результат, а всегда отображает значение, полученное при использовании исходных параметров, а не оптимизированных. К сожалению, я совершенно новичок в R (и в любом программировании) и поэтому не могу решить проблему.

Мои данные для одного примерного подмножества опции выглядят так.

    #Load data    
    #Real option price
    C0116_P=as.vector(c(1328.700000, 1316.050000, 1333.050000, 1337.900000, 1344.800000))
    #Strike price
    C0116_K=as.vector(c(500, 500, 500, 500, 500))
    #Time to maturity in years
    C0116_T_t=as.vector(c(1.660274, 1.657534, 1.654795, 1.652055, 1.649315))
    #Interest rate percentage
    C0116_r=as.vector(c(0.080000, 0.080000, 0.090000, 0.090000, 0.090000))
    #Dividend yield percentage
    C0116_DY=as.vector(c(2.070000, 2.090000, 2.070000, 2.070000,2.060000))
    #Price underlying
    C0116_SP_500_P=as.vector(c(1885.08, 1872.83, 1888.03, 1892.49, 1900.53))

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

    #Load packages
    require(NMOF)
    require(DEoptim)

        #Initial parameters
        v0=0.2
        vT=0.2
        rho=0.2
        k=0.2
        sigma=0.2
        #Define function
        error_heston<-function(x)
        {error<-P-callHestoncf(S, X, tau, r, q, v0, vT, rho, k, sigma)
        return(error)}
        #Run optimization
        outDEoptim<-matrix()
        for (i in 1:5)
        {
        #I only want the parameters v0, vT, rho, k and sigma to change. That is why I kept the others constant
lower<-c(C0116_P[i],C0116_SP_500_P[i],C0116_K[i],C0116_T_t[i],C0116_r[i]/100,C0116_DY[i]/100,0.0001,0.0001,-1,0.0001,0.0001)  
     upper<-c(C0116_P[i],C0116_SP_500_P[i],C0116_K[i],C0116_T_t[i],C0116_r[i]/100,C0116_DY[i]/100,10,10,1,10,10)

        outDEoptim<-(DEoptim(error_heston, lower, upper, DEoptim.control(VTR=0,itermax=100)))  
        print(outDEoptim$opti$bestval)

        i=i+1 
        }

Любая помощь высоко ценится!


person McBiggi    schedule 14.04.2017    source источник
comment
Есть несколько проблем с вашим кодом... Я постараюсь решить их все.   -  person Joshua Ulrich    schedule 15.04.2017


Ответы (1)


Одна из первых проблем заключается в том, что ваша целевая функция имеет только один аргумент (параметры для оптимизации), поэтому все остальные объекты, используемые внутри функции, необходимо искать. Лучше передавать их явно.

Кроме того, многие из необходимых значений не определены в вашем примере (например, S, X и т. д.). Все параметры, которые вы хотите оптимизировать, будут переданы вашей целевой функции через первый аргумент. Это может помочь прояснить ситуацию, если вы явно назначите каждый элемент внутри своей целевой функции. Таким образом, более надежное определение целевой функции:

# Define objective function
error_heston <- function(x, P, S, K, tau, r, q) {
  v0 <- x[1]
  vT <- x[2]
  rho <- x[3]
  k <- x[4]
  sigma <- x[5]
  error <- abs(P - callHestoncf(S, K, tau, r, q, v0, vT, rho, k, sigma))
  return(error)
}

Также обратите внимание, что я взял абсолютную ошибку. DEoptim будет минимизировать целевую функцию, поэтому она попытается сделать P - callHestoncf() как можно более отрицательной, когда вместо этого вы хотите, чтобы она была близка к нулю.

Вы указали ограничения блока upper и lower даже для параметров, которые не изменяются. Лучше всего, чтобы DEoptim генерировало совокупность только для изменяющихся параметров, поэтому я удалил неизменяющиеся параметры из ограничений блока. Я также определил их вне цикла for.

# Only need to set bounds for varying parameters
lower <- c(1e-4, 1e-4, -1, 1e-4, 1e-4)  
upper <- c(  10, 10,    1,   10,   10)

Теперь к фактическому вызову DEoptim. Здесь вы будете передавать значения для всех неизменных параметров. Вы устанавливаете их как именованные аргументы для вызова DEoptim, как я сделал ниже.

i <- 1
outDEoptim <- DEoptim(error_heston, lower, upper,
  DEoptim.control(VTR=0, itermax=100), P = C0116_P[i], S = C0116_SP_500_P[i],
  K = C0116_K[i], tau = C0116_T_t[i], r = C0116_r[i], q = C0116_DY[i])

Я выполнил только одну итерацию цикла for, потому что функция callHestoncf() часто выдает ошибку из-за сбоя процедуры численного интегрирования. Это останавливает оптимизацию. Вы должны выяснить причину этого и задать новый вопрос, если у вас возникнут проблемы.

Я также заметил, что вы неправильно указали один из неизменных входных данных. Ваши проценты дивидендной доходности в 100 раз больше. Ваши неизменные входные данные должны быть:

# Real option price
C0116_P <- c(1328.70, 1316.05, 1333.05, 1337.90, 1344.80)
# Strike price
C0116_K <- c(500, 500, 500, 500, 500)
# Time to maturity in years
C0116_T_t <- c(1.660274, 1.657534, 1.654795, 1.652055, 1.649315)
# Interest rate percentage
C0116_r <- c(0.08, 0.08, 0.09, 0.09, 0.09)
# Dividend yield percentage
C0116_DY <- c(2.07, 2.09, 2.07, 2.07, 2.06) / 100
# Price underlying
C0116_SP_500_P <- c(1885.08, 1872.83, 1888.03, 1892.49, 1900.53)

Кроме того, вам нужно немного времени, чтобы лучше отформатировать код. Это делает его более читабельным, что должно помочь вам избежать ошибок, подобных опечаткам.

person Joshua Ulrich    schedule 15.04.2017
comment
Спасибо, это решило проблему. Я попытаюсь запустить цикл и посмотреть, есть ли другая проблема. В исходном коде я разделил дивидендную доходность на 100 в ограничениях, но теперь я это изменю. Спасибо еще раз! - person McBiggi; 15.04.2017