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
_______________________________________________
R-SIG-Finance@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-sig-finance
-- Subscriber-posting only. If you want to post, subscribe first.
-- Also note that this is not the r-help list where general R questions should
go.