#r #dataframe #user-defined-functions
#r #фрейм данных #определяемые пользователем функции
Вопрос:
У меня есть фрейм данных, и я хочу использовать uniroot в каждой строке для решения подразумеваемой волатильности на основе формулы Блэка-Шоулза. Как правильно использовать uniroot.все, что нужно решить для каждой строки? Это должно привести к созданию нового векторного столбца результатов.
Приведенный ниже код содержит эту ошибку
«Ошибка в 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) ))
Ответ №1:
Первая строка 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"
Ответ №2:
Во-первых: вы должны включить library
инструкцию, которую вы использовали для package 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
(индексы в z
изменены из-за изменения в 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
в качестве ответа.
Остальное зависит от вас.