Compute Local Volatility and Implied Volatility Using the Finance Package
Fitting Implied Volatility Surface
Modeling with Local Volatility
restart:
withLinearAlgebra:withFinance:withStatistics: withplots:interfacedisplayprecision=5:
First let us import prices of S&P 500 call options available on October 27, 2006.
Data:=ImportMatrix⁡FileTools:-JoinPathkerneloptsdatadir,finance,SP-500-CALLS.txt
This data can be stored in a DataFrame.
DF≔DataFrameData2..,..,columns=Data1,..
Extract data from this DataFrame.
M,N≔upperboundDF
M,N≔308,10
Value of the underlying, risk-free rate and dividend yield.
S0:=1377
S0≔1377
r:=0.0532
r≔0.05320
d:=0.0182
d≔0.01820
Extract exercise dates and times for which data is available.
ExerciseDates≔seqNthWeekday⁡3,Friday,DFi,Month,DFi,Year,i=1..M:
Times:=mapt→YearFractionOctober 27, 2006,t,ExerciseDates:
Implied volatilities for options maturing in December 2006.
TimeExample1≔YearFractionOctober 27, 2006,NthWeekday⁡3,Friday, December,2006
TimeExample1≔0.13425
Extract a subset of the DataFrame corresponding to the observations in December 2006:
Dec2006≔DFDFMonth =~ December and DFYear =~ 2006
Compute the implied volatility for these dates and plot the results:
L1≔Matrixseq Dec2006i, Strike, ImpliedVolatility Dec2006i, Ask, S0, Dec2006i, Strike, TimeExample1, r, d , i = 1 .. NumRowsDec2006,datatype=float8
dataplotL1..,1,L1..,2,gridlines,size=600,golden
Implied volatilities for options maturing in December 2007.
TimeExample2≔YearFractionOctober 27, 2006,NthWeekday⁡3,Friday,December,2007
TimeExample2≔1.15068
Extract a subset of the DataFrame corresponding to the observations in December 2007:
Dec2007≔DFDFMonth =~ December and DFYear =~ 2007
L2≔Matrixseq Dec2007i, Strike, ImpliedVolatility Dec2007i, Ask, S0, Dec2007i, Strike, TimeExample2, r, d , i = 1 .. NumRowsDec2007,datatype=float8
dataplotL2..,1,L2..,2,gridlines,size=600,golden
We will use the following model for the volatility surface.
Σ:=S,T,K→α1+α2⁢ln⁡KS+α3T+α4⁢ln⁡KS2+α5⁢ln⁡KST+α6⁢ln⁡KS2T
Σ≔S,T,K↦α1+α2⋅ln⁡KS+α3T+α4⋅ln⁡KS2+α5⋅ln⁡KST+α6⋅ln⁡KS2T
We can compute the corresponding Black-Scholes price as a function of strike and maturity.
C:=BlackScholesPrice⁡S0,K,T,Σ⁡S0,T,K,r,d
C≔1377.00000⁢ⅇ−0.01820⁢T⁢0.50000+0.50000⁢erf⁡0.70711⁢ln⁡1377.00000K+0.03500⁢T+0.50000⁢α1+α2⁢ln⁡0.00073⁢K+α3T+α4⁢ln⁡0.00073⁢K2+α5⁢ln⁡0.00073⁢KT+α6⁢ln⁡0.00073⁢K2T2⁢Tα1+α2⁢ln⁡0.00073⁢K+α3T+α4⁢ln⁡0.00073⁢K2+α5⁢ln⁡0.00073⁢KT+α6⁢ln⁡0.00073⁢K2T⁢T−1.00000⁢ⅇ−0.05320⁢T⁢K⁢0.50000+0.50000⁢erf⁡0.70711⁢ln⁡1377.00000K+0.03500⁢T+0.50000⁢α1+α2⁢ln⁡0.00073⁢K+α3T+α4⁢ln⁡0.00073⁢K2+α5⁢ln⁡0.00073⁢KT+α6⁢ln⁡0.00073⁢K2T2⁢Tα1+α2⁢ln⁡0.00073⁢K+α3T+α4⁢ln⁡0.00073⁢K2+α5⁢ln⁡0.00073⁢KT+α6⁢ln⁡0.00073⁢K2T⁢T−0.70711⁢α1+α2⁢ln⁡0.00073⁢K+α3T+α4⁢ln⁡0.00073⁢K2+α5⁢ln⁡0.00073⁢KT+α6⁢ln⁡0.00073⁢K2T⁢T
We can use non-linear fitting routines from the statistics data to find the values of α1, ..., α6 that best fit our data. Construct a matrix of parameters and a vector of the corresponding value of the objective function.
B:=Times|convertDFStrike,Matrix
V≔convertDFAsk,Vectorcolumn
β1≔NonlinearFitC,B, V,T,K,parameternames=α1,α2,α3,α4,α5,α6,output=parametervector
β1≔
Here is the corresponding implied volatility function.
F1:=Σ⁡S0,T,Kα=β1|Σ⁡S0,T,Kα=β1
F1≔0.14393+0.12599⁢ln⁡K1377−0.01069T−0.03301⁢ln⁡K13772−0.30394⁢ln⁡K1377T+0.40480⁢ln⁡K13772T
plot3d⁡F1,T=0..2.5,K=600..1500,view=0..2.6
animateplot,F1,K=600..1500,thickness=3,T=0.1..3,axes=boxed, gridlines,size=600,golden
Here is another way to estimate these parameters.
U:=Vector⁡1..M
for i to M doUi:=ImpliedVolatilityVi,S0,Bi,2,Bi,1,r,dend do:
β2≔NonlinearFitΣS0,T,K,B,U,T,K,parameternames=α1,α2,α3,α4,α5,α6,output=parametervector
β2≔
F2:=Σ⁡S0,T,Kα=β2|Σ⁡S0,T,Kα=β2
F2≔0.13011+0.17037⁢ln⁡K1377+0.00115T−0.26597⁢ln⁡K13772−0.36133⁢ln⁡K1377T+0.28070⁢ln⁡K13772T
plot3d⁡F2,T=0..2.5,K=600..1500,view=0..2
animateplot,F2,K=600..1500,thickness=3,T=0.1..3, gridlines, axes = boxed,size=600,golden
We can compare both fits with the actual implied volatilities.
P≔dataplotL1..,1,L1..,2:
P1:=plot⁡F1T=TimeExample1|F1T=TimeExample1,K=800..1500,thickness=3,color=red:
P2:=plot⁡F2T=TimeExample1|F2T=TimeExample1,K=800..1500,thickness=3,color=green:
displayP,P1,P2,axes=boxed,gridlines,size=600,golden
P≔dataplotL2..,1,L2..,2:
P1:=plot⁡F1T=TimeExample2|F1T=TimeExample2,K=1000..1500,thickness=3,color=red:
P2:=plot⁡F2T=TimeExample2|F2T=TimeExample2,K=1000..1500,thickness=3,color=green:
displayP,P1,P2,gridlines,axes=boxed,size=600,golden
We will consider the same model for the local volatility except that in this case we will use parameters that were fit to some market data.
restart
withFinance:
Σ:=α1+α2⁢ln⁡KS0+α3⋅1T+α4⁢ln⁡KS02+α5⁢ln⁡KS0T+α6⁢ln⁡KS02T
Σ≔α1+α2⁢ln⁡KS0+α3T+α4⁢ln⁡KS02+α5⁢ln⁡KS0T+α6⁢ln⁡KS02T
α1≔0.1581:α2:=−0.2777:α3:=−0.0050:α4:=−0.5011:α5≔0.1103:α6:=0.5909:
S0:=100
S0≔100
Σ
0.1581−0.2777⁢ln⁡K100−0.0050T−0.5011⁢ln⁡K1002+0.1103⁢ln⁡K100T+0.5909⁢ln⁡K1002T
plot3d⁡Σ,K=50..150,T=0.1..2
Consider two functions. The first one returns the Black-Scholes price of a European call option for our model. The second one returns the Black-Scholes price of a European put option for our model. We will assume that these functions are given two us (e.g. obtained by interpolating the market data) and will try to determine the corresponding local volatility term structure.
C:=BlackScholesPriceS0,K,T,Σ,0.05,0.01,'call':
P:=BlackScholesPrice⁡S0,K,T,Σ,0.05,0.01,'put':
Construct the corresponding local volatility surface.
V:=LocalVolatilitySurface⁡0.05,0.01,C,K,T:
S1:=seq⁡i,i=50..200
T1:=seq⁡0.02⁢i,i=1..50
V:=LocalVolatility⁡C,S1,T1,0.05,0.01,T,K
LV:=LocalVolatility⁡C,S,T,0.05,0.01,T,K:
P1 ≔ plot3dLV,S=50..150,T=0.05..1, color = blue:
P2:=plot3d⁡Σ,K=50..150,T=0.05..1, color = red:
plotsdisplay⁡P1,P2,view=0..1.5
We can construct the corresponding local volatility surface and implied volatility surface.
LVS:=LocalVolatilitySurfaceT1,S1,V:
IVS:=ImpliedVolatilitySurface⁡Σ,T,K:
We can now construct a Black-Scholes process which has the volatility structure we just obtained.
X:=BlackScholesProcess⁡100,LVS,0.05,0.01
X≔_X0
PathPlot⁡Xt,t=0..1,timesteps=20,replications=20,thickness=3,color=red..yellow,axes= boxed, gridlines,size=600,golden
P1:=subs⁡K=S0⁢x,1⁢PS0:
C1:=subsK=S0⁢x,1⁢CS0:
T:='T':
As an alternative, we can use the implied volatility surface to construct an implied trinomial tree.
TT:=ImpliedTrinomialTree⁡100,0.05,0.01,IVS,1,100:
GetLocalVolatility⁡TT,99,99,0.05
0.1531851114
IVS⁡1.0,100
0.1531000000
Compute some option prices. We can use Monte-Carlo simulation to price European-style options and lattice methods to price American-style options.
ExpectedValue⁡max⁡X⁡1−100,0,timesteps=100,replications=104
value=8.562255135,standarderror=0.09642955646
E:=EuropeanOption⁡t→max⁡t−100,0,1.0:
LatticePrice⁡E,TT,0.0
8.477754630
Here is an example of an Asian-type option with European exercise.
ExpectedValue⁡max⁡∫01X⁡uⅆu−100,0,timesteps=100,replications=103
value=4.311947370,standarderror=0.1787554842
Download Help Document