1

I try to compute the local volatility in python in both formula, i.e. in terms of call price surface and total variance surface.

However, I get 2 different values. What did I do wrong?

import numpy as np
from scipy.stats import norm

today=44935

date1=44956 t1 = (date1-today)/365 a1=0.00403326433586633 b1=0.0393291646363571 sigma1=0.103678184440224 rho1=-0.147025189597259 m1=0.0154107775237231

date2=44957 t2 = (date2-today)/365 a2=0.00423386330856259 b2=0.0402496625734392 sigma2=0.106395807290502 rho2=-0.150124616359447 m2=0.0161557212111055

def rawSVI(logMoneyness,a,b,sigma,rho,m): return a + b(rho(logMoneyness-m) + ((logMoneyness-m)2 + sigma2)**0.5)

def bsCall(s,k,r,t,vol): d1 = (np.log(s/k) + (r+0.5vol2)t)/vol/ t0.5 d2 = d1 - vol*t0.5 return snorm.cdf(d1) - knp.exp(-rt)norm.cdf(d2)

w = rawSVI(0,a1,b1,sigma1,rho1,m1) vol = np.sqrt(w/t1)

s = 1 r = 0

k = 0.65 f = snp.exp(rt1) y = np.log(k/f)

#method 1 dk = 0.01 vol = np.sqrt(rawSVI(np.log(k/f),a1,b1,sigma1,rho1,m1)/t1) call = bsCall(s,k,r,t1,vol)

k_plus = k*(1+dk) vol_plus = np.sqrt(rawSVI(np.log(k_plus/f),a1,b1,sigma1,rho1,m1)/t1) call_plus = bsCall(s,k_plus,r,t1,vol_plus)

k_minus = k*(1-dk) vol_minus = np.sqrt(rawSVI(np.log(k_minus/f),a1,b1,sigma1,rho1,m1)/t1) call_minus = bsCall(s,k_minus,r,t1,vol_minus)

call_dkdk = (call_plus - 2*call + call_minus)/(k_plus - k) / (k - k_minus)

vol_tPlus = np.sqrt(rawSVI(np.log(k/f),a2,b2,sigma2,rho2,m2)/t2) call_tPlus = bsCall(s,k,r,t2,vol_tPlus)

call_dt = (call_tPlus - call)/(t2-t1)

localVol_1 = np.sqrt(2call_dt/k*2/call_dkdk) print(localVol_1) #0.9224266360763037

#method 2

dy = 0.01 w = rawSVI(y,a1,b1,sigma1,rho1,m1) w_plus = rawSVI(y(1+dy),a1,b1,sigma1,rho1,m1) w_minus = rawSVI(y(1-dy),a1,b1,sigma1,rho1,m1)

w_dy = (w_plus - w_minus)/(2ydy) w_dydy = (w_plus - 2w + w_minus)/(ydy)**2

w_tPlus = rawSVI(y,a2,b2,sigma2,rho2,m2) w_dt = (w_tPlus - w)/(t2-t1)

localVol_2 = np.sqrt(w_dt/(1-y/ww_dy+0.25(-0.25-1/w+y2/w2)w_dy2+0.5w_dydy)) print(localVol_2) #0.8991455521477574

StupidMan
  • 180
  • 7

0 Answers0