I am trying to implement SABR (Stochastic alpha, beta, rho) in Python to calculate implied volatility. This link here explains SABR very accurately and concisely starting on slide 17: http://lesniewski.us/papers/presentations/MIT_March2014.pdf
The method seems easy enough, but the problem I am having is that I am getting a ZeroDivisonError every time I run the program. I believe this may be because I am choosing my initial alpha, rho, and sigma0 incorrectly during calibration. However, I cannot find online how to choose the initial values to guarantee that a minimum will be found.
Here is my code:
# args = [alpha, rho, sigma0]
# The other parameters (T, K, F0, beta, rho, marketVol) are globals
def calcImpliedVol(args):
alpha = args[0]
rho = args[1]
sigma0 = args[2]
# From MIT powerpoint, slide 21
Fmid = (F0 + K) / 2.0
gamma1 = 1.0 * beta / Fmid
gamma2 = 1.0 * beta * (beta - 1) / Fmid**2
xi = 1.0 * alpha / (sigma0 * (1 - beta)) * (F0**(1-beta) - K**(1-beta))
e = T * alpha**2 # From MIT powerpoint, slide 19
# From MIT powerpoint, slide 21
impliedVol = \
1.0 * alpha * log(F0/K) / D(rho, xi) * \
(1 + ((2 * gamma2 - gamma1**2 + 1 / Fmid**2)/24.0 * (sigma0 * Fmid**beta / alpha)**2 + \
(rho * gamma1 / 4.0) * (sigma0 * Fmid**beta / alpha) + ((2 - 3 * rho**2) / 24.0)) * e) - \
marketVol
# Returns lambda function in terms of alpha, rho, sigma0
return impliedVol;
# From MIT powerpoint, slide 21
def D(rho, xi):
result = log((sqrt(1 - 2 * rho * xi + xi**2) + xi - rho) / (1-rho))
return result
# Find optimal alpha, rho, sigma0 that minimizes calcImpliedVol - marketVol
def optimize():
result = optimize.minimize(calcImpliedVol, [alpha_init, rho_init, sigma0_init])
return result
Thanks so, so much for any help!