def BiNormalProb(a, b, rho):
    x = [0.24840615, 0.39233107, 0.21141819, 0.03324666, 0.00082485334]
    y = [0.10024215, 0.48281397, 1.0609498, 1.7797294, 2.6697604]
    a1 = a / math.sqrt(2 * (1 - math.pow(rho, 2)))
    b1 = b / math.sqrt(2 * (1 - math.pow(rho, 2)))
    if a <= 0 and b <= 0 and rho <= 0:
        sum = 0
        for i in range(0, 4):
            for j in range(0, 4):
                z1 = a1 * (2 * y[i] - a1)
                z2 = b1 * (2 * y[j] - b1)
                z3 = 2 * rho * (y[i] - a1) * (y[j] - b1)
                sum = sum + x[i] * x[j] * math.exp(z1 + z2 + z3)
        return sum * math.sqrt(1 - math.pow(rho, 2)) / math.pi
    elif a <= 0 and b >= 0 and rho >= 0:
        return cumulative_standard_normal(a) - BiNormalProb(a, b * -1, rho * -1)
    elif a >= 0 and b <= 0 and rho >= 0:
        return cumulative_standard_normal(b) - BiNormalProb(a * -1, b, rho * -1)
    elif a >= 0 and b >= 0 and rho <= 0:
        sum = cumulative_standard_normal(a) + cumulative_standard_normal(b)
        return sum - 1 + BiNormalProb(a * -1, b * -1, rho)
    elif a * b * rho > 0:
        rho1 = (rho * a - b) * np.sign(a) / np.sign(math.pow(a, 2) - 2 * rho * a * b + math.pow(b, 2))
        rho2 = (rho * b - a) * np.sign(b) / math.sqrt(math.pow(a, 2) - 2 * rho * a * b + math.pow(b, 2))
        Delta = (1 - np.sign(a) * np.sign(b)) / 4
        return BiNormalProb(a, 0, rho1) + BiNormalProb(b, 0, rho2) - Delta
Esempio n. 2
0
def Generic_Option(P1, P2, sigma, T):
    # inputs
    """P1 = present value of asset to be received
       P2 = present value of asset to be delivered
       sigma = volatility
       T = time to maturity"""
    x = (math.log(P1 / P2) + 0.5 * sigma * sigma * T) / (sigma * math.sqrt(T))
    y = x - sigma * math.sqrt(T)
    N1 = cumulative_standard_normal(x)
    N2 = cumulative_standard_normal(y)
    return P1 * N1 - P2 * N2
def Black_Scholes_Call_Delta(S, K, r, sigma, q, T):
    # inputs
    """ S = initial stock price
        K = strike price
        r = risk-free rate
        sigma = volatility
        q = dividend yield
        T = time to maturity"""
    d1 = (math.log(S / K) +
          (r - q + 0.5 * sigma * sigma) * T) / (sigma * math.sqrt(T))
    d2 = d1 - sigma * math.sqrt(T)
    n1 = cumulative_standard_normal(d1)
    n2 = cumulative_standard_normal(d2)
    return round(math.exp(-q * T) * n1, 4)
def Black_Scholes_Put(S, K, r, sigma, q, T):
    # inputs
    """ S = initial stock price
        K = strike price
        r = risk-free rate
        sigma = volatility
        q = dividend yield
        T = time to maturity"""
    if sigma == 0:
        return round(max(0, math.exp(-r * T) * K - math.exp(-q * T) * S), 4)
    else:
        d1 = (math.log(S / K) +
              (r - q + 0.5 * sigma * sigma) * T) / (sigma * math.sqrt(T))
        d2 = d1 - sigma * math.sqrt(T)
        n1 = cumulative_standard_normal(-d1)
        n2 = cumulative_standard_normal(-d2)
        return round(math.exp(-r * T) * K * n2 - math.exp(-q * T) * S * n1, 4)
def Call_On_Call(S, Kc, Ku, r, sigma, q, Tc, Tu):
    # inputs
    """S = initial stock price
       Kc = strike price of compound call
       Ku = strike price of underlying call option
       r = risk-free rate
       sigma = volatility
       q = dividend yield
       Tc = time to maturity of compound call
       Tu = time to maturity of underlying call >= Tc"""
    tol = math.pow(10, -6)
    lower = 0
    upper = math.exp(q * (Tu - Tc)) * (Kc + Ku)
    guess = 0.5 * lower + 0.5 * upper
    flower = -Kc
    fupper = Black_Scholes_Call(upper, Ku, r, sigma, q, Tu - Tc) - Kc
    fguess = Black_Scholes_Call(guess, Ku, r, sigma, q, Tu - Tc) - Kc
    while upper - lower > tol:
        if fupper * fguess < 0:
            lower = guess
            flower = fguess
            guess = 0.5 * lower + 0.5 * upper
            fguess = Black_Scholes_Call(guess, Ku, r, sigma, q, Tu - Tc) - Kc
        else:
            upper = guess
            fupper = fguess
            guess = 0.5 * lower + 0.5 * upper
            fguess = Black_Scholes_Call(guess, Ku, r, sigma, q, Tu - Tc) - Kc
    Sstar = guess
    #print(Sstar)

    d1 = (math.log(S / Sstar) + (r - q + math.pow(sigma, 2) / 2) * Tc) / (sigma * math.sqrt(Tc))
    d2 = d1 - sigma * math.sqrt(Tc)
    d1prime = (math.log(S / Ku) + (r - q + math.pow(sigma, 2) / 2) * Tu) / (sigma * math.sqrt(Tu))
    d2prime = d1prime - sigma * math.sqrt(Tu)
    rho = math.sqrt(Tc / Tu)
    #print(d1)
    #print(d2)
    #print(rho)
    N2 = cumulative_standard_normal(d2)
    print(N2)
    M1 = BiNormalProb(d1, d1prime, rho)
    print(M1)
    M2 = BiNormalProb(d2, d2prime, rho)
    print(M2)
    return -math.exp(-r * Tc) * Kc * N2 + math.exp(-q * Tu) * S * M1 - math.exp(-r * Tu) * Ku * M2