Example #1
0
def delta(flag, S, K, t, r, sigma, q):
    
    """Returns the Black-Scholes-Merton delta of an option.
    

    :param flag: 'c' or 'p' for call or put.
    :type flag: str
    :param S: underlying asset price
    :type S: float
    :param K: strike price
    :type K: float
    :param t: time to expiration in years
    :type t: float
    :param r: annual risk-free interest rate
    :type r: float
    :param sigma: volatility
    :type sigma: float
    :param q: annualized continuous dividend yield
    :type q: float
    
    :returns:  float 

    """

    D1 = d1(S, K, t, r, sigma, q)

    if flag == 'p':
        return -numpy.exp(-q*t) * cnd(-D1)
    else:
        return numpy.exp(-q*t) * cnd(D1)
Example #2
0
def black_put(F, K, t, r, sigma):  #Equation 16.10
    """Calculate the price of a put using Black.  (Python
    implementation for reference.)

    :param F: underlying futures price
    :type F: float
    :param K: strike price
    :type K: float
    :param sigma: annualized standard deviation, or volatility
    :type sigma: float
    :param t: time to expiration in years
    :type t: float
    :param r: risk-free interest rate
    :type r: float        
    
    
    Hull, page 338, example 16.6

    >>> F = 20
    >>> K = 20
    >>> r = .09
    >>> sigma = .25
    >>> t = 4/12.0
    >>> calculated_value = black_put(F, K, t, r, sigma)
    >>> # 1.11664145656
    >>> text_book_value = 1.12
    >>> abs(calculated_value - text_book_value) < .01
    True
    """
    e_to_the_minus_rt = numpy.exp(-r * t)
    N_of_minus_d1 = cnd(-d1(F, K, t, r, sigma))
    N_of_minus_d2 = cnd(-d2(F, K, t, r, sigma))

    return e_to_the_minus_rt * (-F * N_of_minus_d1 + K * N_of_minus_d2)
Example #3
0
def python_black_scholes(flag, S, K, t, r, sigma):
    
    """Return the Black-Scholes option price implemented in
        python (for reference).

    :param S: underlying asset price
    :type S: float
    :param K: strike price
    :type K: float
    :param sigma: annualized standard deviation, or volatility
    :type sigma: float
    :param t: time to expiration in years
    :type t: float
    :param r: risk-free interest rate
    :type r: float
    :param flag: 'c' or 'p' for call or put.
    :type flag: str    
    
    >>> S,K,t,r,sigma = 60,65,.25,.08,.3
    >>> c1 = black_scholes('c',S,K,t,r,sigma) 
    >>> c2 = python_black_scholes('c',S,K,t,r,sigma)    
    >>> abs(c1 - c2) < .00001
    True
    >>> abs(c1 - 2.13336844492) < .00001
    True
    """
    
    e_to_the_minus_rt = numpy.exp(-r*t)
    D1 = d1(S, K, t, r, sigma)
    D2 = d2(S, K, t, r, sigma)
    if flag == 'c':
        return S * cnd(D1) - K * e_to_the_minus_rt * cnd(D2)
    else:
        return - S * cnd(-D1) + K * e_to_the_minus_rt * cnd(-D2)
Example #4
0
def delta(flag, S, K, t, r, sigma, q):
    """Returns the Black-Scholes-Merton delta of an option.
    

    :param flag: 'c' or 'p' for call or put.
    :type flag: str
    :param S: underlying asset price
    :type S: float
    :param K: strike price
    :type K: float
    :param t: time to expiration in years
    :type t: float
    :param r: annual risk-free interest rate
    :type r: float
    :param sigma: volatility
    :type sigma: float
    :param q: annualized continuous dividend yield
    :type q: float
    
    :returns:  float 

    """

    D1 = d1(S, K, t, r, sigma, q)

    if flag == 'p':
        return -numpy.exp(-q * t) * cnd(-D1)
    else:
        return numpy.exp(-q * t) * cnd(D1)
Example #5
0
def theta(flag, F, K, t, r, sigma):

    """Returns the Black theta of an option.

    :param flag: 'c' or 'p' for call or put.
    :type flag: str
    :param F: underlying futures price
    :type F: float
    :param K: strike price
    :type K: float
    :param t: time to expiration in years
    :type t: float
    :param r: annual risk-free interest rate
    :type r: float
    :param sigma: volatility
    :type sigma: float

    :returns:  float 

    >>> F = 49
    >>> K = 50 
    >>> r = .05
    >>> t = 0.3846
    >>> sigma = 0.2
    >>> flag = 'c'
    >>> v1 = theta(flag, F, K, t, r, sigma)
    >>> v2 = -0.00816236877462
    >>> abs(v1-v2) < .000001
    True
    >>> flag = 'p'
    >>> v1 = theta(flag, F, K, t, r, sigma)
    >>> v2 = -0.00802799155312
    >>> abs(v1-v2) < .000001
    True
    """

    e_to_the_minus_rt = numpy.exp(-r * t)
    two_sqrt_t = 2 * numpy.sqrt(t)

    D1 = d1(F, K, t, r, sigma)
    D2 = d2(F, K, t, r, sigma)
    pdf_d1 = pdf(D1)
    cnd_d2 = cnd(D2)

    first_term = F * e_to_the_minus_rt * pdf(D1) * sigma / two_sqrt_t

    if flag == "c":
        second_term = -r * F * e_to_the_minus_rt * cnd(D1)
        third_term = r * K * e_to_the_minus_rt * cnd(D2)
        return -(first_term + second_term + third_term) / 365.0
    else:
        second_term = -r * F * e_to_the_minus_rt * cnd(-D1)
        third_term = r * K * e_to_the_minus_rt * cnd(-D2)
        return (-first_term + second_term + third_term) / 365.0

    return (first_term - second_term) / 365.0
def theta(flag, F, K, t, r, sigma):
    """Returns the Black theta of an option.

    :param flag: 'c' or 'p' for call or put.
    :type flag: str
    :param F: underlying futures price
    :type F: float
    :param K: strike price
    :type K: float
    :param t: time to expiration in years
    :type t: float
    :param r: annual risk-free interest rate
    :type r: float
    :param sigma: volatility
    :type sigma: float

    :returns:  float 

    >>> F = 49
    >>> K = 50 
    >>> r = .05
    >>> t = 0.3846
    >>> sigma = 0.2
    >>> flag = 'c'
    >>> v1 = theta(flag, F, K, t, r, sigma)
    >>> v2 = -0.00816236877462
    >>> abs(v1-v2) < .000001
    True
    >>> flag = 'p'
    >>> v1 = theta(flag, F, K, t, r, sigma)
    >>> v2 = -0.00802799155312
    >>> abs(v1-v2) < .000001
    True
    """

    e_to_the_minus_rt = numpy.exp(-r * t)
    two_sqrt_t = 2 * numpy.sqrt(t)

    D1 = d1(F, K, t, r, sigma)
    D2 = d2(F, K, t, r, sigma)
    pdf_d1 = pdf(D1)
    cnd_d2 = cnd(D2)

    first_term = F * e_to_the_minus_rt * pdf(D1) * sigma / two_sqrt_t

    if flag == 'c':
        second_term = -r * F * e_to_the_minus_rt * cnd(D1)
        third_term = r * K * e_to_the_minus_rt * cnd(D2)
        return -(first_term + second_term + third_term) / 365.
    else:
        second_term = -r * F * e_to_the_minus_rt * cnd(-D1)
        third_term = r * K * e_to_the_minus_rt * cnd(-D2)
        return (-first_term + second_term + third_term) / 365.0

    return (first_term - second_term) / 365.0
Example #7
0
def rho(flag, S, K, t, r, sigma):

    """Return Black-Scholes rho of an option.
    
    :param S: underlying asset price
    :type S: float
    :param K: strike price
    :type K: float
    :param sigma: annualized standard deviation, or volatility
    :type sigma: float
    :param t: time to expiration in years
    :type t: float
    :param r: risk-free interest rate
    :type r: float
    :param flag: 'c' or 'p' for call or put.
    :type flag: str      
    
    The text book analytical formula does not multiply by .01,
    but in practice rho is defined as the change in price
    for each 1 percent change in r, hence we multiply by 0.01.


    Example 17.7, page 368, Hull:

    >>> S = 49
    >>> K = 50 
    >>> r = .05
    >>> t = 0.3846
    >>> sigma = 0.2
    >>> flag = 'c'
    >>> rho_calc = rho(flag, S, K, t, r, sigma)
    >>> # 0.089065740988
    >>> rho_text_book = 0.0891
    >>> abs(rho_calc - rho_text_book) < .0001
    True

    """

    d_2 = d2(S, K, t, r, sigma)
    e_to_the_minus_rt = numpy.exp(-r*t)
    if flag == 'c':
        return t*K*e_to_the_minus_rt * cnd(d_2) * .01
    else:
        return -t*K*e_to_the_minus_rt * cnd(-d_2) * .01
Example #8
0
def theta(flag, S, K, t, r, sigma, q):

    """Returns the Black-Scholes-Merton theta of an option.


    :param flag: 'c' or 'p' for call or put.
    :type flag: str
    :param S: underlying asset price
    :type S: float
    :param K: strike price
    :type K: float
    :param t: time to expiration in years
    :type t: float
    :param r: annual risk-free interest rate
    :type r: float
    :param sigma: volatility
    :type sigma: float
    :param q: annualized continuous dividend yield
    :type q: float

    :returns:  float 

    """


    D1 = d1(S, K, t, r, sigma, q)
    D2 = d2(S, K, t, r, sigma, q)

    first_term = (S * numpy.exp(-q*t) * pdf(D1) * sigma) / (2 * numpy.sqrt(t))

    if flag == 'c':

        second_term = -q * S * numpy.exp(-q*t) * cnd(D1)
        third_term = r * K * numpy.exp(-r*t) * cnd(D2)

        return - (first_term + second_term + third_term) / 365.0

    else:

        second_term = -q * S * numpy.exp(-q*t) * cnd(-D1)
        third_term = r * K * numpy.exp(-r*t) * cnd(-D2)

        return (-first_term + second_term + third_term) / 365.0
Example #9
0
def theta(flag, S, K, t, r, sigma, q):
    """Returns the Black-Scholes-Merton theta of an option.


    :param flag: 'c' or 'p' for call or put.
    :type flag: str
    :param S: underlying asset price
    :type S: float
    :param K: strike price
    :type K: float
    :param t: time to expiration in years
    :type t: float
    :param r: annual risk-free interest rate
    :type r: float
    :param sigma: volatility
    :type sigma: float
    :param q: annualized continuous dividend yield
    :type q: float

    :returns:  float 

    """

    D1 = d1(S, K, t, r, sigma, q)
    D2 = d2(S, K, t, r, sigma, q)

    first_term = (S * numpy.exp(-q * t) * pdf(D1) * sigma) / (2 *
                                                              numpy.sqrt(t))

    if flag == 'c':

        second_term = -q * S * numpy.exp(-q * t) * cnd(D1)
        third_term = r * K * numpy.exp(-r * t) * cnd(D2)

        return -(first_term + second_term + third_term) / 365.0

    else:

        second_term = -q * S * numpy.exp(-q * t) * cnd(-D1)
        third_term = r * K * numpy.exp(-r * t) * cnd(-D2)

        return (-first_term + second_term + third_term) / 365.0
def bsm_put(S, K, t, r, sigma, q):

    
    """Return the Black-Scholes-Merton put price
    implemented in python (for reference).

    :param S: underlying asset price
    :type S: float
    :param K: strike price
    :type K: float
    :param sigma: annualized standard deviation, or volatility
    :type sigma: float
    :param t: time to expiration in years
    :type t: float
    :param r: risk-free interest rate
    :type r: float
    :param q: annualized continuous dividend rate
    :type q: float 
  
    
    
    From Espen Haug, The Complete Guide To Option Pricing Formulas
    Page 4

    >>> S=100
    >>> K=95
    >>> q=.05
    >>> t = 0.5
    >>> r = 0.1
    >>> sigma = 0.2

    >>> p_published_value = 2.4648
    >>> p_calc = bsm_put(S, K, t, r, sigma, q)
    >>> abs(p_published_value - p_calc) < 0.0001
    True

    """     
    
    D1 = d1(S, K, t, r, sigma, q)
    D2 = d2(S, K, t, r, sigma, q)
    return K * numpy.exp(-r*t) * cnd(-D2) - S * numpy.exp(-q*t) * cnd(-D1)
Example #11
0
def delta(flag, S, K, t, r, sigma):
    
    """Return Black-Scholes delta of an option.
    
    
    :param S: underlying asset price
    :type S: float
    :param K: strike price
    :type K: float
    :param sigma: annualized standard deviation, or volatility
    :type sigma: float
    :param t: time to expiration in years
    :type t: float
    :param r: risk-free interest rate
    :type r: float
    :param flag: 'c' or 'p' for call or put.
    :type flag: str      
    
    
    Example 17.1, page 355, Hull:
    
    >>> S = 49
    >>> K = 50 
    >>> r = .05
    >>> t = 0.3846
    >>> sigma = 0.2
    >>> flag = 'c'
    >>> delta_calc = delta(flag, S, K, t, r, sigma)
    >>> # 0.521601633972
    >>> delta_text_book = 0.522
    >>> abs(delta_calc - delta_text_book) < .01
    True
    """

    d_1 = d1(S, K, t, r, sigma)

    if flag == 'p':
        return cnd(d_1) - 1.0
    else:
        return cnd(d_1)
Example #12
0
def delta(flag, F, K, t, r, sigma):

    """Returns the Black delta of an option.

    :param flag: 'c' or 'p' for call or put.
    :type flag: str
    :param F: underlying futures price
    :type F: float
    :param K: strike price
    :type K: float
    :param t: time to expiration in years
    :type t: float
    :param r: annual risk-free interest rate
    :type r: float
    :param sigma: volatility
    :type sigma: float

    :returns:  float 
      
    
    >>> F = 49
    >>> K = 50 
    >>> r = .05
    >>> t = 0.3846
    >>> sigma = 0.2
    >>> flag = 'c'
    >>> v1 = delta(flag, F, K, t, r, sigma)
    >>> v2 = 0.45107017482201828
    >>> abs(v1-v2) < .000001
    True
    """

    D1 = d1(F, K, t, r, sigma)

    if flag == "p":
        return -numpy.exp(-r * t) * cnd(-D1)
    else:
        return numpy.exp(-r * t) * cnd(D1)
Example #13
0
def black_call(F, K, t, r, sigma):  #Equation 16.9
    

    """Calculate the price of a call using Black.  (Python
    implementation for reference.)

    :param F: underlying futures price
    :type F: float
    :param K: strike price
    :type K: float
    :param sigma: annualized standard deviation, or volatility
    :type sigma: float
    :param t: time to expiration in years
    :type t: float
    :param r: risk-free interest rate
    :type r: float    
    
    
    
    Hull, page 343, example 16.7
    
    >>> F = 620
    >>> K = 600
    >>> r = .05
    >>> sigma = .2
    >>> t = 0.5
    >>> calculated_value = black_call(F, K, t, r, sigma)
    >>> #44.1868533121
    >>> text_book_value = 44.19
    >>> abs(calculated_value - text_book_value) < .01
    True
    """
    
    e_to_the_minus_rt = numpy.exp(-r*t)
    N_d1 = cnd(d1(F, K, t, r, sigma))
    N_d2 = cnd(d2(F, K, t, r, sigma))
    
    return e_to_the_minus_rt * (F * N_d1 - K * N_d2) 
def bsm_call(S, K, t, r, sigma, q):

    """Return the Black-Scholes-Merton call price
    implemented in python (for reference).
    
    :param S: underlying asset price
    :type S: float
    :param K: strike price
    :type K: float
    :param sigma: annualized standard deviation, or volatility
    :type sigma: float
    :param t: time to expiration in years
    :type t: float
    :param r: risk-free interest rate
    :type r: float
    :param q: annualized continuous dividend rate
    :type q: float 
    """
   
    D1 = d1(S, K, t, r, sigma, q)
    D2 = d2(S, K, t, r, sigma, q)    
    
    return S * numpy.exp(-q*t) * cnd(D1) - K * numpy.exp(-r*t) * cnd(D2)
def delta(flag, F, K, t, r, sigma):
    """Returns the Black delta of an option.

    :param flag: 'c' or 'p' for call or put.
    :type flag: str
    :param F: underlying futures price
    :type F: float
    :param K: strike price
    :type K: float
    :param t: time to expiration in years
    :type t: float
    :param r: annual risk-free interest rate
    :type r: float
    :param sigma: volatility
    :type sigma: float

    :returns:  float 
      
    
    >>> F = 49
    >>> K = 50 
    >>> r = .05
    >>> t = 0.3846
    >>> sigma = 0.2
    >>> flag = 'c'
    >>> v1 = delta(flag, F, K, t, r, sigma)
    >>> v2 = 0.45107017482201828
    >>> abs(v1-v2) < .000001
    True
    """

    D1 = d1(F, K, t, r, sigma)

    if flag == 'p':
        return -numpy.exp(-r * t) * cnd(-D1)
    else:
        return numpy.exp(-r * t) * cnd(D1)
Example #16
0
def black_put(F, K, t, r, sigma):  #Equation 16.10


    """Calculate the price of a put using Black.  (Python
    implementation for reference.)

    :param F: underlying futures price
    :type F: float
    :param K: strike price
    :type K: float
    :param sigma: annualized standard deviation, or volatility
    :type sigma: float
    :param t: time to expiration in years
    :type t: float
    :param r: risk-free interest rate
    :type r: float        
    
    
    Hull, page 338, example 16.6

    >>> F = 20
    >>> K = 20
    >>> r = .09
    >>> sigma = .25
    >>> t = 4/12.0
    >>> calculated_value = black_put(F, K, t, r, sigma)
    >>> # 1.11664145656
    >>> text_book_value = 1.12
    >>> abs(calculated_value - text_book_value) < .01
    True
    """
    e_to_the_minus_rt = numpy.exp(-r*t)
    N_of_minus_d1 = cnd(-d1(F, K, t, r, sigma))
    N_of_minus_d2 = cnd(-d2(F, K, t, r, sigma))

    return e_to_the_minus_rt * ( -F * N_of_minus_d1 + K * N_of_minus_d2)
Example #17
0
def black_call(F, K, t, r, sigma):  #Equation 16.9
    """Calculate the price of a call using Black.  (Python
    implementation for reference.)

    :param F: underlying futures price
    :type F: float
    :param K: strike price
    :type K: float
    :param sigma: annualized standard deviation, or volatility
    :type sigma: float
    :param t: time to expiration in years
    :type t: float
    :param r: risk-free interest rate
    :type r: float    
    
    
    
    Hull, page 343, example 16.7
    
    >>> F = 620
    >>> K = 600
    >>> r = .05
    >>> sigma = .2
    >>> t = 0.5
    >>> calculated_value = black_call(F, K, t, r, sigma)
    >>> #44.1868533121
    >>> text_book_value = 44.19
    >>> abs(calculated_value - text_book_value) < .01
    True
    """

    e_to_the_minus_rt = numpy.exp(-r * t)
    N_d1 = cnd(d1(F, K, t, r, sigma))
    N_d2 = cnd(d2(F, K, t, r, sigma))

    return e_to_the_minus_rt * (F * N_d1 - K * N_d2)
Example #18
0
def theta(flag, S, K, t, r, sigma):

    """Return Black-Scholes theta of an option.
    
    :param S: underlying asset price
    :type S: float
    :param K: strike price
    :type K: float
    :param sigma: annualized standard deviation, or volatility
    :type sigma: float
    :param t: time to expiration in years
    :type t: float
    :param r: risk-free interest rate
    :type r: float
    :param flag: 'c' or 'p' for call or put.
    :type flag: str      
    
    
    The text book analytical formula does not divide by 365,
    but in practice theta is defined as the change in price
    for each day change in t, hence we divide by 365.

    Example 17.2, page 359, Hull:

    >>> S = 49
    >>> K = 50 
    >>> r = .05
    >>> t = 0.3846
    >>> sigma = 0.2
    >>> flag = 'c'
    >>> annual_theta_calc = theta(flag, S, K, t, r, sigma) * 365
    >>> # -4.30538996455
    >>> annual_theta_text_book = -4.31
    >>> abs(annual_theta_calc - annual_theta_text_book) < .01
    True
    
    
    Using the same inputs with a put.
    >>> S = 49
    >>> K = 50 
    >>> r = .05
    >>> t = 0.3846
    >>> sigma = 0.2
    >>> flag = 'p'
    >>> annual_theta_calc = theta(flag, S, K, t, r, sigma) * 365
    >>> # -1.8530056722
    >>> annual_theta_reference = -1.8530056722
    >>> abs(annual_theta_calc - annual_theta_reference) < .000001
    True
    
    
    """
    
    two_sqrt_t = 2 * numpy.sqrt(t)

    D1 = d1(S, K, t, r, sigma)
    D2 = d2(S, K, t, r, sigma)

    first_term = (-S * pdf(D1) * sigma) / two_sqrt_t 

    if flag == 'c':

        second_term = r * K * numpy.exp(-r*t) * cnd(D2)
        return (first_term - second_term)/365.0
    
    if flag == 'p':
    
        second_term = r * K * numpy.exp(-r*t) * cnd(-D2)
        return (first_term + second_term)/365.0