fixing interpolation over volatility surface graph in R programming
Asked Answered
T

1

8

This script below pulls yahoo data via a function in quantmod, then massages the data around to forumalate a 3D graph with RGL library, attached is a ggplot to show the data i'm trying to create a surface with in separate line geoms . the issue is that the 3D graph looks very ugly and cut up because of the limited quantities of points on the front month expirations.. can anyone tell me whats going on here , what i can do to fix this.. do i need to smooth each expiration's line then interpolate.... ?? volsurface http://img15.imageshack.us/img15/7338/surface.png ggplot2_smile http://img402.imageshack.us/img402/1272/volatilitysmilegoog.png

library(RQuantLib)
library(quantmod)
library(rgl)
library(akima)
library(ggplot2)
library(plyr)

GetIV <- function(type, value,
                  underlying, strike,dividendYield, riskFreeRate, maturity, volatility,
                  timeSteps=150, gridPoints=151) {

    AmericanOptionImpliedVolatility(type, value,
                                    underlying, strike,dividendYield, riskFreeRate, maturity, volatility,
                                    timeSteps=150, gridPoints=151)$impliedVol
}


GetDelta <- function(type, underlying, strike,
                     dividendYield, riskFreeRate, maturity, volatility, 
                     timeSteps=150, gridPoints=149, engine="CrankNicolson") {

    AmericanOption(type,underlying, strike, dividendYield, riskFreeRate, maturity, volatility,
                   timeSteps=150, gridPoints=149, engine="CrankNicolson")$delta
}
# set what symbol you want vol surface for
underlying <- 'GOOG'
# set what your volatility forcast or assumption is
volforcast <- .25
# Get symbols current price
underlying.price <- getQuote(underlying,what=yahooQF("Last Trade (Price Only)"))$Last

OC <- getOptionChain(underlying, NULL)
#check data
head(OC)
lputs <- lapply(OC, FUN = function(x) x$puts[grep("[A-Z]\\d{6}[CP]\\d{8}$", rownames(x$puts)), ])
head(lputs) #check for NA values, yahoo returns all NA values sometimes
puts <- do.call('rbind', lputs )
#check data
head(puts,5)

symbols <- as.vector(unlist(lapply(lputs, rownames)))
expiries <- unlist(lapply(symbols, FUN = function(x) regmatches(x=x, regexpr('[0-9]{6}', x) )))
puts$maturity <- as.numeric((as.Date(expiries, "%y%m%d") - Sys.Date())/365)

puts$IV <- mapply(GetIV, value = puts$Ask, strike = puts$Strike, maturity = puts$maturity,
                  MoreArgs= list(type='put', underlying= underlying.price,
                                 dividendYield=0, riskFreeRate = 0.01,  
                                 volatility = volforcast), SIMPLIFY=TRUE)

puts$delta <- mapply(GetDelta, strike =  puts$Strike, volatility = puts$IV,
                     maturity = puts$maturity, MoreArgs= list(type='put', 
                                                              underlying=underlying.price, dividendYield=0, 
                                                              riskFreeRate = 0.01 ), SIMPLIFY=TRUE)

# subset out itm puts
puts <- subset(puts, delta < -.09 & delta > -.5 )

expiries.formated <- format(as.Date(levels(factor(expiries)), format = '%y%m%d'), "%B %d, %Y")

fractionofyear.levels <- levels(factor(puts$maturity))

xyz <- with(puts, interp(x=maturity, y=delta*100, z=IV*100, 
                         xo=sort(unique(maturity)), extrap=FALSE ))

with(xyz, persp3d(x,y,z, col=heat.colors(length(z))[rank(z)], xlab='maturity', 
                  ylab='delta', zlab='IV', main='IV Surface'))

putsplot <- ggplot(puts, aes(delta, IV, group = factor(maturity), color = factor(maturity))) +
    labs(x = "Delta", y = "Implied Volatilty", title="Volatility Smile", color = "GooG \nExpiration") +
    scale_colour_discrete( breaks=c(fractionofyear.levels),
                           labels=c(expiries.formated)) + 
    geom_line() +
    geom_point()

putsplot
Tricyclic answered 31/3, 2013 at 1:46 Comment(3)
does anyone know how to fix the interpolation in the front months here?Tricyclic
do you know if i could just turn the points into line objects of some sort and interpolate all the lines instead of the pointsTricyclic
no progress with this so far.. i don't get how the variables map to the aesthetics here. i've read in depth the akima interpolation method.. but don't get it. cran.r-project.org/web/packages/akima/akima.pdf not sure if there is a way to smooth the data and see the actual points on the surface.. still on my missionTricyclic
P
3

The akima package is exactly what you need, but I think you need to decrease the number of interpolated points in your y-axis, the delta variable. The way you have it set right now uses the default 40-point grid.

# No interpolation on x-axis, but uses the default 40 point grid on the y-axis
xyz <- with(puts, interp(x=maturity, y=delta*100, z=IV*100, 
            xo=sort(unique(maturity)), extrap=FALSE ))
# By setting to use less points, it will "stretch" the surface over those points.
xyz <- with(puts, interp(x=maturity, y=delta*100, z=IV*100, 
            xo=sort(unique(maturity)), 
            yo=seq(min(delta*100), max(delta*100), length = 15), extrap=FALSE ))

Surface smoothed by y-axis

You can play with the length variable in the seq function to get differing levels of smoothness.


I still don't completely understand what you want, but maybe you want to smooth by maturity? Here is what that would look like:

# This smooths just by x.
xyz <- with(puts, interp(x=maturity, y=delta*100, z=IV*100, 
            xo=seq(min(maturity), max(maturity), length = 5), 
            , extrap=FALSE ))

with(xyz, persp3d(x,y,z, col=heat.colors(length(z))[rank(z)], xlab='maturity', 
                  ylab='delta', zlab='IV', main='IV Surface'))

enter image description here

Phylloid answered 11/5, 2013 at 6:55 Comment(8)
Yea... I really only wanna smooth the delta values of each expiration to them selves but not between expirationsTricyclic
@Tricyclic Hm, I am unfamiliar with your particular domain. Could you describe what you don't want to smooth in terms of delta, maturity and IV? I don't really get which one is "expirations". Also, I think that delta is the only thing being smoothed here.Phylloid
there are discrete maturities.....the delta values are derived from the price of options at a particular strike price.. so i'd like to smooth the options delta across its own expiration... the idea is your trying to differentiate pricing between maturities by delta.. so you don't want to smooth between maturities.. i only wanna smooth each maturities delta values to themselves not other maturities.. this way you can see the calender risk by delta.. does that make sense?Tricyclic
@Tricyclic Actually, I have a hard time making sense of it because I don't know what an option, discrete maturity or an expiration is. However, I have smoothed by the maturity axis alone, and by the delta axis alone... I am guess you want it smoothed only on the maturity axis, which is what I think I did in the second picture.Phylloid
@nograpes... delta is a measure of the rate of change of the price of an options with respect to the rate of change in the underlying asset.. so a delta of .20 means the option price will go up .20 cents per 1 dollar change in the underlying.. underlying = stock, commodity, index, etc.. an Options is a the right or obligation to buy or sell the underlying at a set price "strike".. they are derivatives. one question.. in the expression xo=seq(min(maturity), max(maturity), length = 5) what does length = 5 represent.Tricyclic
@Tricyclic Perhaps I was unclear: it isn't important what the actual terms mean. It would help if you described what you wanted in terms of the plot itself. For example, if you wanted to help someone in epidemiology (my field) draw this kind of plot, you wouldn't ask them about the diseases in question, but what they wanted to see, and how they wanted to smooth in terms of x, y, and z.Phylloid
@Tricyclic Take a look at ?seq. You'll see that length=5 means find five equally spaced points from min(maturity) to max(maturity). Now take a look at ?interp. You'll see that what it does is smooth to a grid of points. Take a look at the default grid generated in the xo and yo arguments. By making less points on this grid, the surface will become smoother.Phylloid
you are very correct.. i shouldn't have went into depth with that.. i am just trying to smooth the individual maturities.. between maturities is discrete in this case and the differential between maturities is what i am trying to study... i'm going to try different equally spaced points on xo... thanks for your patienceTricyclic

© 2022 - 2024 — McMap. All rights reserved.