Как использовать uniroot для решения пользовательской функции (UDF) в кадре данных? - PullRequest
0 голосов
/ 23 марта 2019

У меня есть фрейм данных, и я хочу использовать uniroot в каждой строке для решения подразумеваемой волатильности на основе формулы Блэка-Шоулза. Как правильно использовать uniroot.all для решения каждой строки? Он должен создать новый вектор-столбец результатов.

Код ниже имеет эту ошибку

«Ошибка в S / K: нечисловой аргумент для двоичного оператора»

. Я подозреваю, что проблема возникает, когда uniroot пытается решить несколько строк вместо каждой строки одна за другой.

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

df <- data.frame( strike = c(80,120,100,100), 
                  type = c("C", "C", "C","C"),
                  optionPrice = c(22,3,7,9),
                  futurePrice = c(100, 100,100,100),
                  time_to_expiry = c(0.1, 0.1,1,1.2))

bscall <-
  function (S,K,r,T,sig) {
    d1 <- (log(S/K)+(r+0.5*sig^2)*T) / (sig*sqrt(T)) 
    d2 <- d1 - sig*sqrt(T)
    price <- S*pnorm(d1) - K*exp(-r*T)*pnorm(d2)
    return(price)
  }


apply(df, 1,
      function(z) uniroot.all( function(x) bscall(z[4],z[1],r,z[5],x) - z[3], interval = c(0,1) ))

Ответы [ 2 ]

0 голосов
/ 23 марта 2019

Первое: вы должны включить оператор library, который вы использовали для пакета rootSolve.Где определены переменные r и sig?

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

Определите df следующим образом с учетом первого ответа.

df <- data.frame( strike = c(80,120,100,100), 
                  # type = c("C", "C", "C","C"),
                  optionPrice = c(22,3,7,9),
                  futurePrice = c(100, 100,100,100),
                  time_to_expiry = c(0.1, 0.1,1,1.2))

Колонка type закомментирована.

Определите вашу функцию bscall как

bscall <-
  function (S,K,r,T,sig) {
  d1 <- (log(S/K)+(r+0.5*sig^2)*T) / (sig*sqrt(T)) 
  d2 <- d1 - sig*sqrt(T)
  price <- S*pnorm(d1) - K*exp(-r*T)*pnorm(d2)
  return(price)
}

Дайте r и sig значение

r <- .05
sig <- 1

Примените вашу функцию к строкам df (индексы в * 1028)* изменено из-за изменения на df)

apply(df, 1,
   function(z) bscall(z[3],z[1],r,z[4],sig) - z[2])

давая

[1]  2.258107  3.168623 32.840162 34.366636

в качестве ответа.

Остальное зависит от вас.

0 голосов
/ 23 марта 2019

Первый ряд df равен 80, "C", 22, 100, 0.1. Содержит строку символов. Поэтому, когда вы делаете apply(df, 1, ....), строки приводятся к символьным векторам:

df <- data.frame( strike = c(80,120,100,100), 
                  type = c("C", "C", "C","C"),
                  optionPrice = c(22,3,7,9),
                  futurePrice = c(100, 100,100,100),
                  time_to_expiry = c(0.1, 0.1,1,1.2))

apply(df, 1, function(z) z)
#                [,1]  [,2]  [,3]  [,4] 
# strike         " 80" "120" "100" "100"
# type           "C"   "C"   "C"   "C"  
# optionPrice    "22"  " 3"  " 7"  " 9" 
# futurePrice    "100" "100" "100" "100"
# time_to_expiry "0.1" "0.1" "1.0" "1.2"
...