Compute Local Volatility and Implied Volatility Using the Finance Package - Maple Programming Help

Online Help

All Products    Maple    MapleSim


Home : Support : Online Help : Applications and Example Worksheets : Finance : Finance/Examples/LocalVolatility

Compute Local Volatility and Implied Volatility Using the Finance Package

 

Fitting Implied Volatility Surface

Modeling with Local Volatility

Fitting Implied Volatility Surface

restart:

withLinearAlgebra:withFinance:withStatistics: withplots:interfacedisplayprecision=5:

 

First let us import prices of  S&P 500 call options available on October 27, 2006.

Data:=ImportMatrixFileTools:-JoinPathkerneloptsdatadir,finance,SP-500-CALLS.txt

Data 309 x 10 MatrixData Type: anythingStorage: rectangularOrder: Fortran_order

(1.1)

This data can be stored in a DataFrame.

DFDataFrameData2..,..,columns=Data1,..

DFMonthYearStrikeSymbolLastChangeBidAsk...1November2006800.00000SPXKT578.000007.40000578.00000580.00000...2November2006850.00000SPXKJ527.900007.70000527.90000529.90000...3November2006900.00000SXBKT478.8000010.80000478.00000480.00000...4November2006950.00000SXBKJ4.600002.90000428.50000430.50000...5November20061000.00000SPQKT378.700007.40000378.70000380.70000...6November20061025.00000SPQKE353.700007.50000353.70000355.70000...7November20061050.00000SPQKJ0.250000.20000328.80000330.80000...8November20061075.00000SPQKO303.900007.50000303.90000305.90000.................................

(1.2)

 

Extract data from this DataFrame.

M,NupperboundDF

M,N308,10

(1.3)

Value of the underlying, risk-free rate and dividend yield.

S0:=1377

S01377

(1.4)

r:=0.0532

r0.05320

(1.5)

d:=0.0182

d0.01820

(1.6)

 

Extract exercise dates and times for which data is available.

ExerciseDatesseqNthWeekday3,Friday,DFi,Month,DFi,Year,i=1..M:

Times:=maptYearFractionOctober 27, 2006,t,ExerciseDates:

Implied volatilities for options maturing in December 2006.

Time1YearFractionOctober 27, 2006,NthWeekday3,Friday, December,2006

Time10.13425

(1.7)

Extract a subset of the DataFrame corresponding to the observations in December 2006:

Dec2006DFDFMonth =~ December and DFYear =~ 2006

Dec2006MonthYearStrikeSymbolLastChangeBidAsk...79December2006600.00000SYGLT788.0000019.20000777.90000779.90000...80December2006700.00000SPZLT633.0000023.10000678.60000680.60000...81December2006750.00000SPZLJ629.000007.40000629.00000631.00000...82December2006800.00000SPXLT480.000002.00000579.30000581.30000...83December2006850.00000SPXLJ483.000000.00000529.70000531.70000...84December2006900.00000SXBLT429.0000075.00000480.10000482.10000...85December2006925.00000SXBLE398.500000.00000455.30000457.30000...86December2006950.00000SXBLJ308.500000.00000430.40000432.40000.................................

(1.8)

Compute the implied volatility for these dates and plot the results:

L1Matrixseq  Dec2006i, Strike, ImpliedVolatility Dec2006i, Ask, S0, Dec2006i, Strike, Time1, r, d  , i = 1 .. NumRowsDec2006,datatype=float8

L1 72 x 2 MatrixData Type: float8Storage: rectangularOrder: Fortran_order

(1.9)

dataplotL1..,1,L1..,2,gridlines,size=600,golden

 

Implied volatilities for options maturing in December 2007.

Time2YearFractionOctober 27, 2006,NthWeekday3,Friday,December,2007

Time21.15068

(1.10)

Extract a subset of the DataFrame corresponding to the observations in December 2007:

Dec2007DFDFMonth =~ December and DFYear =~ 2007

Dec2007MonthYearStrikeSymbolLastChangeBidAsk...256December2007900.00000SZJLT25.000001.50000500.20000503.20000...257December2007950.00000SZJLW128.500004.90000454.20000457.20000...258December20071000.00000SZTLR330.000000.00000409.90000412.90000...259December20071050.00000SZTLJ251.000000.00000365.00000368.00000...260December20071075.00000SZTLX342.800000.50000342.80000345.80000...261December20071100.00000SZTLT224.5000022.00000320.90000323.90000...262December20071125.00000SZTLC227.0000024.50000297.90000300.90000...263December20071150.00000SZTLY260.000004.00000277.80000280.80000.................................

(1.11)

Compute the implied volatility for these dates and plot the results:

L2Matrixseq  Dec2007i, Strike, ImpliedVolatility Dec2007i, Ask, S0, Dec2007i, Strike, Time2, r, d  , i = 1 .. NumRowsDec2007,datatype=float8

L2 24 x 2 MatrixData Type: float8Storage: rectangularOrder: Fortran_order

(1.12)

dataplotL2..,1,L2..,2,gridlines,size=600,golden

 

We will use the following model for the volatility surface.

Σ:=S,T,K→α1+α2lnKS+α3T+α4lnKS2+α5lnKST+α6lnKS2T

ΣS,T,K→α1+α2lnKS+α3T+α4lnKS2+α5lnKST+α6lnKS2T

(1.13)

 

We can compute the corresponding Black-Scholes price as a function of strike and maturity.

C:=BlackScholesPriceS0,K,T,ΣS0,T,K,r,d

C1377.00000ⅇ0.01820T0.50000+0.50000erf0.70711ln1377.00000K+0.03500T+0.50000α1+α2ln0.00073K+α3T+α4ln0.00073K2+α5ln0.00073KT+α6ln0.00073K2T2Tα1+α2ln0.00073K+α3T+α4ln0.00073K2+α5ln0.00073KT+α6ln0.00073K2TT1.00000ⅇ0.05320TK0.50000+0.50000erf0.70711ln1377.00000K+0.03500T+0.50000α1+α2ln0.00073K+α3T+α4ln0.00073K2+α5ln0.00073KT+α6ln0.00073K2T2Tα1+α2ln0.00073K+α3T+α4ln0.00073K2+α5ln0.00073KT+α6ln0.00073K2TT0.70711α1+α2ln0.00073K+α3T+α4ln0.00073K2+α5ln0.00073KT+α6ln0.00073K2TT

(1.14)

 

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

B 308 x 2 MatrixData Type: anythingStorage: rectangularOrder: Fortran_order

(1.15)

VconvertDFAsk,Vectorcolumn

V 1 .. 308 VectorcolumnData Type: anythingStorage: rectangularOrder: Fortran_order

(1.16)

β1NonlinearFitC,B, V,T,K,parameternames=α1,α2,α3,α4,α5,α6,output=parametervector

β10.143930.125990.010690.033010.303940.40480

(1.17)

 

Here is the corresponding implied volatility function.

F1:=ΣS0,T,Kα=β1|ΣS0,T,Kα=β1

F10.14393+0.12599ln11377K0.01069T0.03301ln11377K20.30394ln11377KT+0.40480ln11377K2T

(1.18)

plot3dF1,T=0..2.5,K=600..1500

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:=Vector1..M

U 1 .. 308 VectorcolumnData Type: anythingStorage: rectangularOrder: Fortran_order

(1.19)

for i to M doUi:=ImpliedVolatilityVi,S0,Bi,2,Bi,1,r,dend do:

β2NonlinearFitΣS0,T,K,B,U,T,K,parameternames=α1,α2,α3,α4,α5,α6,output=parametervector

β20.130110.170370.001150.265970.361330.28070

(1.20)

 

Here is the corresponding implied volatility function.

F2:=ΣS0,T,Kα=β2|ΣS0,T,Kα=β2

F20.13011+0.17037ln11377K+0.00115T0.26597ln11377K20.36133ln11377KT+0.28070ln11377K2T

(1.21)

plot3dF2,T=0..2.5,K=600..1500

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.

PdataplotL1..,1,L1..,2:

P1:=plotF1T=Time1|F1T=Time1,K=800..1500,thickness=3,color=red:

P2:=plotF2T=Time1|F2T=Time1,K=800..1500,thickness=3,color=green:

displayP,P1,P2,axes=boxed,gridlines,size=600,golden

PdataplotL2..,1,L2..,2:

P1:=plotF1T=Time2|F1T=Time2,K=1000..1500,thickness=3,color=red:

P2:=plotF2T=Time2|F2T=Time2,K=1000..1500,thickness=3,color=green:

displayP,P1,P2,gridlines,axes=boxed,size=600,golden

Modeling with Local Volatility

 

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+α2lnKS0+α31T+α4lnKS02+α5lnKS0T+α6lnKS02T

Σα1+α2lnKS0+α3T+α4lnKS02+α5lnKS0T+α6lnKS02T

(2.1)

α10.1581:α2:=0.2777:α3:=0.0050:α4:=0.5011:α50.1103:α6:=0.5909:

S0:=100

S0100

(2.2)

Σ

0.158100.27770ln1100K0.00500T0.50110ln1100K2+0.11030ln1100KT+0.59090ln1100K2T

(2.3)

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:=BlackScholesPriceS0,K,T,Σ,0.05,0.01,'put':

 

Construct the corresponding local volatility surface.

V:=LocalVolatilitySurface0.05,0.01,C,K,T:

S1:=seqi,i=50..200

S1 1 .. 151 VectorcolumnData Type: anythingStorage: rectangularOrder: Fortran_order

(2.4)

T1:=seq0.02i,i=1..50

T1 1 .. 50 VectorcolumnData Type: anythingStorage: rectangularOrder: Fortran_order

(2.5)

V:=LocalVolatilityC,S1,T1,0.05,0.01,T,K

V 151 x 50 MatrixData Type: anythingStorage: rectangularOrder: Fortran_order

(2.6)

LV:=LocalVolatilityC,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..1, color = red:

plotsdisplayP1,P2

 

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:=BlackScholesProcess100,LVS,0.05,0.01

X_X

(2.7)

PathPlotXt,t=0..1,timesteps=20,replications=20,thickness=3,color=red..yellow,axes= boxed, gridlines,size=600,golden

P1:=subsK=S0x,1PS0:

C1:=subsK=S0x,1CS0:

T:='T'

TT

(2.8)

 

As an alternative, we can use the implied volatility surface to construct an implied trinomial tree.

TT:=ImpliedTrinomialTree100,0.05,0.01,IVS,1,100:

GetLocalVolatilityTT,99,99,0.05

0.15319

(2.9)

IVS1.0,100

0.15310

(2.10)

 

Compute some option prices. We can use Monte-Carlo simulation to price European-style options and lattice methods to price American-style options.

ExpectedValuemaxX1100,0,timesteps=100,replications=104

value=8.55963,standarderror=0.09592

(2.11)

E:=EuropeanOptiont→maxt100,0,1.0

Emodule...end module

(2.12)

LatticePriceE,TT,0.0

8.47775

(2.13)

 

Here is an example of an Asian-type option with European exercise.

ExpectedValuemax∫01Xuⅆu100,0,timesteps=100,replications=103

value=4.45120,standarderror=0.18170

(2.14)