[R-SIG-Finance] GBSVolatility not working on vectors?

Joachim Breit jbreit at nexgo.de
Thu Sep 25 14:03:30 CEST 2014


Thanks a lot Joe. Will try the "try"-trick...
I only now realize that my question has been asked before:
https://stat.ethz.ch/pipermail/r-sig-finance/2010q4/006900.html
Sorry about that.

This also seems to be related
http://dirk.eddelbuettel.com/blog/2012/10/25/

Joachim

Am 25.09.2014 13:00, schrieb Joe W. Byers:
> On 09/25/2014 04:47 AM, Joachim Breit wrote:
>> Hi,
>>
>> I am struggling with the GBSVolatility function. I have a huge dataframe
>> 'd' with options market data and want to add a column with the implied
>> volatility computed from the ask price.
>>
>> When invoking GBSVolatility with a single line of the dataframe
>> everything works fine. But when feeding the columns of the dataframe
>> into GBSVolatility I get an error message.
>>
>> To tackle the issue I took a mini-dataframe 'dtemp' with only two rows
>> (arbitrary subset of the original d)
>>
>> ## mini-dataframe ########################################
>>  > dtemp <- d[515:516,]
>>  > dtemp
>>       strike cp   ask   bid     c ntd      rb   iva
>> 1081     50  c 16.17 15.37 65.79  32 0.00384 1e+09
>> 1083     51  c 15.17 14.37 65.79  32 0.00384 1e+09
>>
>> ## invoking with the entire mini-dataframe ####################
>>  > dtemp$iva  <- GBSVolatility(price = dtemp$ask, TypeFlag = dtemp$cp,
>> S = dtemp$c , X = dtemp$strike, Time = dtemp$ntd / 253.8,
>> r = pmax(dtemp$rb, 0), b = pmax(dtemp$rb, 0))
>> Fehler in uniroot(.fGBSVolatility, interval = c(-10, 10), price =
>> price,  :
>>    ungültiger Funktionswert in 'zeroin'
>> Zusätzlich: Warnmeldungen:
>> 1: In if (is.na(f.lower)) stop("f.lower = f(lower) is NA") :
>>    Bedingung hat Länge > 1 und nur das erste Element wird benutzt
>> 2: In if (is.na(f.upper)) stop("f.upper = f(upper) is NA") :
>>    Bedingung hat Länge > 1 und nur das erste Element wird benutzt
>> 3: In if (f.lower * f.upper > 0) stop("f() values at end points not of
>> opposite sign") :
>>    Bedingung hat Länge > 1 und nur das erste Element wird benutzt
>>
>>
>> ## invoking with the first row of the mini-dataframe ###############
>>  > dtemp <- d[515:515,]
>>  > dtemp$iva  <- GBSVolatility(price = dtemp$ask, TypeFlag = dtemp$cp,
>> S = dtemp$c , X = dtemp$strike, Time = dtemp$ntd / 253.8,
>> r = pmax(dtemp$rb, 0), b = pmax(dtemp$rb, 0))
>>  > dtemp
>>       strike cp   ask   bid     c ntd      rb       iva
>> 1081     50  c 16.17 15.37 65.79  32 0.00384 0.5340467
>>
>> ## invoking with the 2nd row of the mini-dataframe ###############
>>  > dtemp <- d[516:516,]
>>  > dtemp$iva  <- GBSVolatility(price = dtemp$ask, TypeFlag = dtemp$cp, S
>> = dtemp$c , X = dtemp$strike, Time = dtemp$ntd / 253.8, r =
>> pmax(dtemp$rb, 0), b = pmax(dtemp$rb, 0))
>>  > dtemp
>>       strike cp   ask   bid     c ntd      rb       iva
>> 1083     51  c 15.17 14.37 65.79  32 0.00384 0.5030617
>>
>>
>> Can somebody please help? I am going crazy...
>>
>> Joachim
>>
>
> Joachim
>
>
> Try something like this.  I have this in an automated task calculating
> Energy IV's every day.  res is a dataframe of option characteristics.  I
> use a Try statement for basic error trap.  This is rough but works.
>
>    # need to error trap options that will not return a valid Vol.  This
> occurs at
>    # option  strikes close to zero and short time to expiraton.
>    done = F;
>    idx = as.logical(matrix(1, nrow=dim(res)[1],ncol=1)) ;
>    res$IV = NaN; #initialize all IV's to NaNs
>    while( !done){
>      try({
>        cat('impliedVolatilityCurve: calculator trying\n')
>        res$IV[idx] = mapply(GBSVolatility,price=res$Settle[idx],
> TypeFlag=lowerCase(res$Type[idx]),
>           S=res$Underlying[idx], X=res$Strike[idx],
> Time=as.numeric(res$Texp[idx]), r=res$RFRate[idx],
>           b=0, tol=10e-3, maxiter=300, USE.NAMES=T);
>        done = T;
>        cat('impliedVolatilityCurve: calculator completed try\n')
>        })#, silent=T)
>      if (!done){ idx = res$Strike>1.00; }
>
>    }
>
> This works for what I needed.  I set the tolerance to 10e-3 because
> prices are quotes in 3 decimal places and this is an estimated parameter
> so it is close enough.  The last if(!done) traps strikes less than a
> 1.00 for energy commodities.  This will need to be modified for other
> option markets.
>
> Good Luck
> Joe
>
>



More information about the R-SIG-Finance mailing list