简体   繁体   中英

Python scipy.optimize.minimize gives ZeroDivisionError

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!

限定搜索间隔。

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM