如何使用uniroot解决数据帧中的用户定义函数(UDF)?

时间:2019-03-23 10:45:31

标签: r dataframe user-defined-functions

我有一个数据框,并希望在每一行上使用uniroot来基于Black-Scholes公式求解隐含波动率。使用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 :(得分:0)

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"

答案 1 :(得分:0)

首先:您应该包括用于软件包library的{​​{1}}语句。 变量rootSolver在哪里定义?

检查功能sig可以看到,uniroot.all并不需要。无需迭代。 bscall是直接根据输入计算得出的。

根据第一个答案,对df进行如下定义。

price

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 行(由于更改为dfz的索引已更改)

df

给予

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

作为答案。

其余的取决于您。