def call_lower_bound_and_out(spot, vol, mat, strike, interest, bound): m = m_fct(interest, vol) factor = np.power((bound / spot), 2 * m / (vol * vol)) spot_adj = bound * bound / spot call_1 = m1.bsOptionPrice(spot, vol, mat, bound, interest, 0, "call") call_2 = m1.bsOptionPrice(spot_adj, vol, mat, bound, interest, 0, "call") call_3 = m1.bsOptionPrice(spot, vol, mat, strike, interest, 0, "call") call_4 = m1.bsOptionPrice(spot_adj, vol, mat, strike, interest, 0, "call") return call_1 - factor * call_2 - (call_3 - factor * call_4)
def merton_option_price(spot, vol, mat, strike, r, lambdaa, m, v): price_element = 1 price = 0 n = 0 # jump_stat = m + 0.5*v # comp = lambdaa * (np.exp(jump_stat) - 1) lambda_dt = lambdaa * (1 + m) * mat gamma = np.log(1 + m) while price_element > 0.00001: r_tilde = r + (n * gamma) / mat - lambdaa * m # spot_tilde = spot*np.exp(n*jump_stat - comp * mat) vol_tilde = np.sqrt(vol * vol + n * v / mat) # Without hashtags spot below should be replaced by spot_tilde cond_price = m1.bsOptionPrice(spot, vol_tilde, mat, strike,\ r_tilde, 0, "call") weight = np.exp(-lambda_dt) * np.power(lambda_dt, n) / factorial(n) price_element = cond_price * weight price += price_element n += 1 return price
inter_snr = np.zeros((len(spot), len(mat))) inter_jnr = np.zeros((len(spot), len(mat))) # --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- # # (b) Deriving stock payoff, bond payoff and yield spread. for i in spot: ix = spot.index(i) # Payoffs: jmp s_jmp[ix, :] = m_jmp_func(i, vol, mat, debt_ttl, r, lambdaa, m, v) b_jmp_snr[ix, :] = i - m_jmp_func(i, vol, mat, debt_snr, r, lambdaa, m, v) b_jmp_jnr[ix,:] = m_jmp_func(i, vol, mat, debt_snr, r, lambdaa, m, v) -\ m_jmp_func(i, vol, mat, debt_ttl, r, lambdaa, m, v) # Payoffs: std s_std[ix, :] = m1.bsOptionPrice(i, vol, mat, debt_ttl, r, q, 'call') b_std_snr[ix, :] = i - m1.bsOptionPrice(i, vol, mat, debt_snr, r, q, 'call') b_std_jnr[ix, :] = m1.bsOptionPrice(i, vol, mat, debt_snr, r, q, 'call') -\ m1.bsOptionPrice(i, vol, mat, debt_ttl, r, q, 'call') # Credit spreads: jmp y_jmp_snr[ix, :] = 100 * (1 / mat * np.log(debt_snr / b_jmp_snr[ix, :]) - r) y_jmp_jnr[ix, :] = 100 * (1 / mat * np.log(debt_jnr / b_jmp_jnr[ix, :]) - r) # Credit spreads: std y_std_snr[ix, :] = 100 * (1 / mat * np.log(debt_snr / b_std_snr[ix, :]) - r) y_std_jnr[ix, :] = 100 * (1 / mat * np.log(debt_jnr / b_std_jnr[ix, :]) - r)
# Model parameters spot = 100 r = 0.01 # risk free return rate q = 0.0 # Dividends mu = 0.05 # real return rate (not used here) vol = 0.25 mat = 1 # Being at t = 0 this functions also as time_to_mat. debt_junior = 50 debt_senior = 50 debt_total = debt_junior + debt_senior # Firm value is denoted by FV FV = np.arange(1, 201, 1) # S = Stock, B = bond, where debt_i functions as strike price s = m1.bsOptionPrice(FV, vol, mat, debt_total, r, q, "call") b_senior = FV - m1.bsOptionPrice(FV, vol, mat, debt_senior, r, q, "call") b_junior = m1.bsOptionPrice(FV, vol, mat, debt_senior, r, q, "call") -\ m1.bsOptionPrice(FV, vol, mat, debt_total, r, q, "call") # --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- # # 2. Risk structure of stocks and bonds # New model parameters (Firm value is now given by V) V = (50, 100, 150) mat = 30 time_to_mat = np.arange(1, mat + 1, 1) s_rs = np.zeros((mat, 2 * len(V))) b_senior_rs = np.zeros((mat, 2 * len(V)))
def c_lo_bs(spot, vol, mat, strike, interest, dividends, bound, bound_rate): spot_adj = bound * bound / spot r_tilde = interest - 0.5 * vol * vol factor = np.power(bound / spot, 2 * r_tilde / (vol*vol)) return np.where(bound < strike, m1.bsOptionPrice(spot, vol, mat, strike, interest, dividends, "call") -\ factor * m1.bsOptionPrice(spot_adj, vol, mat, strike, interest, dividends, "call"),0)
bond_b = B_b(spot, vol, mat, r, q, bound, gamma) # --------------------------------------------------------------------------- # bond_barrier = B(spot, vol, mat, debt, r, q, bound, gamma) y_barrier = 1 / mat * np.log(debt / bond_barrier) s_barrier = 10000 * (y_barrier - r) # --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- # # (c) Merton base case # --------------------------------------------------------------------------- # bond_standard = spot - m1.bsOptionPrice(spot, vol, mat, debt, r, q, "call") y_standard = 1 / mat * np.log(debt / bond_standard) s_standard = 10000 * (y_standard - r) # --------------------------------------------------------------------------- # # =========================================================================== # # =========================== Comparative Statics =========================== # # =========================================================================== # spot = 120 debt = 100 mat = np.arange(0.01,10.01,0.01) vol_1 = 0.2 vol_2 = 0.3