0

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!

Erniu
  • 125
  • 4
  • Probably the solver uses parameter combinations which results 7 a zero denominator. Eg. Sigma =0. You might wand to use inequality constraints – Moritz Sep 04 '15 at 22:12
  • you have the variable 'beta' in calcImpliedVol, but it is not specified anywhere in the 'args', or in the optimize arguments. That value seems to be missing? – Kiann Mar 13 '19 at 23:47

2 Answers2

1

This is a little late but bounding is the right way to go:

bounds = [(0.0001, None), (-0.9999, 0.9999), (0.0001, None)]
x_solved = minimize(obj_func, initial_guess, args=(mkt_vols, F, K, tau, beta),
                    method='L-BFGS-B', bounds=bounds, tol=0.00001)

alpha represents the base volatility (atm vol can be used here to as an initialization) so it is bounded by 0.0. rho is the correlation between the axes so it is bounded by -1 and 1. nu (vol of volatility) is bounded on the downside by 0.0.

The coefficient tuple is returned with:

   x_solved.x
user2606310
  • 66
  • 1
  • 5
0

Work with bounding the search intervals.