Ejemplo n.º 1
0
def bsimpvol(callput, S0, K, r, T, price, sigma, q=0, priceTolerance=0.01, method='bisect', reportCalls=False):
    def targetfunction(x):
        return bsformula(callput, S0, K, r, T, x, q)[0]
        
    def getReturnData(_impVol, _calls):
        if (reportCalls):
            return (_impVol, _calls)
        else:
            return _impVol

    if (isNoVolatilityCanBeFound(callput, price, S0, K, T)):
        return getReturnData(float('NaN'), 0)
    
    impvol = float('NaN')
    calls = 0
    
    if (method=="bisect"):
        start = 0.50
        result = bisect(price, targetfunction, start, None, [priceTolerance, priceTolerance])
        impvol = result[-1]
        calls = len(result)
    elif (method=="newton"):
        result = newtonsMethod(callput, S0, K, r, T, q, price, sigma, priceTolerance)
        impvol = result[0]
        calls = result[1]            
    else:
        result = secantMethodBS(price, targetfunction, callput, S0, K, r, T, q, priceTolerance)
        impvol = result[0]
        calls = result[1]

    return getReturnData(impvol, calls)
def bsimpvol(callput,
             S0,
             K,
             r,
             T,
             price,
             q=0.,
             priceTolerance=0.01,
             method='bisect',
             reportCalls=False):
    '''
    :param callput: Callput is 1 for a call and -1 for a put
    :param S0: The stock price at time zero
    :param K: The strike price
    :param r: Risk-free interest rate
    :param T: The maturity time
    :param price: The price of the option
    :param q: A continuous return rate on the underlying
    :param priceTolerance:
    :param method: The method used to calculate sigma
    :param reportCalls: The record of call bsformula
    :return: sigma, numbers of calling bsformula
    '''

    y = lambda sigma: bsformula(callput, S0, K, r, T, sigma)[0]
    dy = lambda sigma: bsformula(callput, S0, K, r, T, sigma)[2]
    if method == 'bisect':
        if bisect(price, y, bounds=[0.01, 1])[0] == None:
            return None
        item = bisect(price, y, bounds=[0.01, 1])[0]
    elif method == 'newton':
        if newton(price, y, dy, start=1, bounds=[0.01, 1])[0] == None:
            return None
        item = newton(price, y, dy, start=1, bounds=[0.01, 1])[0]

    if item != None:
        sigma = item[-1]
    else:
        sigma = item
        return None
    if reportCalls == True:
        return (sigma, len(item))
    else:
        return sigma
Ejemplo n.º 3
0
def bsimpvol(callput,
             S0,
             K,
             r,
             T,
             price,
             q=0.0,
             priceTollerance=0.01,
             method='bisect',
             reportCalls=False):
    #judge which method to use
    'return NaN'
    # no input value
    input_Value = [callput, S0, K, r, T]
    if all(input_Value) is False:
        return 'NaN'
    # price is less than intrinsic value
    if callput == 1:
        if price < max(0, S0 - K):
            return 'NaN'
    if callput == -1:
        if price < max(0, K - S0):
            return 'NaN'

    # call bsformula
    # create f function and df for methods
    def optionValue(x):
        return bsformula(callput, S0, K, r, T, x, q)[0]

    def optVega(x):
        return bsformula(callput, S0, K, r, T, x, q)[2]

    # use bisection method
    if method == 'bisect':
        (volatility, callsTimes) = bisect(price, optionValue, 0.001,
                                          [-0.001, 15],
                                          [0.001, priceTollerance], 1000)
        #if reportCalls is true
        if reportCalls == True:
            return (volatility[callsTimes - 1], callsTimes)
        else:
            return volatility[callsTimes - 1]
    # use newton method
    elif method == 'newton':
        (volatility, callsTimes) = newton_Method(price, optionValue, optVega,
                                                 0.8, [0.001, priceTollerance],
                                                 1000)
        #if reportCalls is true
        if reportCalls == True:
            return (volatility, callsTimes)
        else:
            return volatility
    else:
        print("please input 'bisect' or 'newton' in method")
Ejemplo n.º 4
0
def bsimpvol(callput,
             S0,
             K,
             r,
             T,
             price,
             q=0.,
             priceTolerance=0.01,
             method='bisect',
             reportCalls=False):

    if price != 'NaN' and price >= callput * (S0 - K):

        def bsmvsact(sigma, callput, S0, K, r, T, price):

            return bsformula(callput, S0, K, r, T, sigma, q=0.)[0] - price

        def vega(sigma, callput, S0, K, r, T):

            return bsformula(callput, S0, K, r, T, sigma, q=0.)[2]

        partial_bsmvsact = partial(bsmvsact,
                                   callput=callput,
                                   S0=S0,
                                   K=K,
                                   r=r,
                                   T=T,
                                   price=price)
        partial_vega = partial(vega, callput=callput, S0=S0, K=K, r=r, T=T)

        if method == 'bisect':
            root, diff, iterations = bisect(0, partial_bsmvsact, None, [0, 2],
                                            [0.00001, 0.0001], 1000)
            n_calls = iterations

        elif method == 'newton':
            root, diff, iterations = newton(0, partial_bsmvsact, partial_vega,
                                            1.0, 0, [0.00001, 0.0001], 1000)
            n_calls = 2 * iterations

        if root:
            if reportCalls: return root[-1], n_calls
            else: return root[-1]
        else:
            if reportCalls: return 'NaN', n_calls
            else: return 'NaN'

    else: return 'NaN'
Ejemplo n.º 5
0
def impliedVol(callput, price, S0, T, K, r, tolerence):
    def obejctFunc(x):
        return BS(callput, S0, K, T, r, x)

    if callput == "call" and (price > S0 or
                              price < positivePart(S0 - K * np.exp(-r * T))):
        print "invalid call price"
        return float('nan')
    elif callput == "put" and (price < positivePart(K * np.exp(-r * T) - S0)
                               or price > K * np.exp(-r * T)):
        print "invalid put price"
        print T, K, price
        return float('nan')
    start = 0.30
    result = bisect(price, obejctFunc, start, None, tolerence)
    impVol = result[-1]
    return impVol
Ejemplo n.º 6
0
def bsimpvol(callput,
             S0,
             K,
             r,
             T,
             price,
             sigma,
             q=0,
             priceTolerance=0.01,
             method='bisect',
             reportCalls=False):
    def targetfunction(x):
        return bsformula(callput, S0, K, r, T, x, q)[0]

    def getReturnData(_impVol, _calls):
        if (reportCalls):
            return (_impVol, _calls)
        else:
            return _impVol

    if (isNoVolatilityCanBeFound(callput, price, S0, K, T)):
        return getReturnData(float('NaN'), 0)

    impvol = float('NaN')
    calls = 0

    if (method == "bisect"):
        start = 0.50
        result = bisect(price, targetfunction, start, None,
                        [priceTolerance, priceTolerance])
        impvol = result[-1]
        calls = len(result)
    elif (method == "newton"):
        result = newtonsMethod(callput, S0, K, r, T, q, price, sigma,
                               priceTolerance)
        impvol = result[0]
        calls = result[1]
    else:
        result = secantMethodBS(price, targetfunction, callput, S0, K, r, T, q,
                                priceTolerance)
        impvol = result[0]
        calls = result[1]

    return getReturnData(impvol, calls)
def bsimpvol(callput,
             S0,
             K,
             r,
             T,
             price,
             q=0.,
             priceTolerance=0.01,
             method='bisect'):
    """
    :param callput: Indicates if the option is a Call or Put option
    :param S0: Stock price
    :param K: Strike price
    :param r: Risk-free rate
    :param T: Time to expiration
    :param price: Price of option
    :param q: Dividend rate
    :param priceTolerance: The precision of the solution
    :param method: Specifies if Bisection method or Newton's method is to be used
    :return: Implied Volatility
    """
    sigma = 0.5

    def targetfunction(x):
        return bsformula(callput, S0, K, r, T, x, q)[0]

    if (isnan(S0) or isnan(K) or isnan(r) or isnan(T) or isnan(price)):
        return float('NaN')
    if ((callput == 1 and price < (S0 - K)) or (callput == -1 and price <
                                                (K - S0))):
        return float('NaN')

    if method == 'newton':
        sigma_est = newton(callput, S0, K, r, T, q, price, sigma,
                           priceTolerance)
    if method == 'bisect':
        sigma_est = (bisect(price,
                            targetfunction,
                            start=0.5,
                            tols=[priceTolerance, priceTolerance]))[0]

    return sigma_est
Ejemplo n.º 8
0
def bsimpvol(callput,
             S0,
             K,
             r,
             T,
             price,
             q=0,
             priceTolerance=0.01,
             init=0,
             max_iter=100,
             method='bisect'):
    '''
    :param callput:judgement for option
    :param S0:intial value of the underlying
    :param K:the strike price
    :param r:interest rate
    :param T:time to maturity
    :param price:theoretical price under BS formula
    :param q:continuous return rate on the underlying
    :param priceTolerance:criterion to stop the process
    :param method:judgement to use bisect method or newton method
    :return:implied volatility and iteration
    '''

    sigma = init  #np.random.random()
    results = []

    def f(x):
        return bsformula(callput, S0, K, r, T, x, q)[0] - price

    if method == 'bisect':
        results = bisect(0, f, None, [0.001, 1.0],
                         [priceTolerance, priceTolerance], max_iter)

    else:

        def f_prime(x):
            return bsformula(callput, S0, K, r, T, x, q)[2]

        results = newton(f, f_prime, sigma, priceTolerance, max_iter)
    return results