def bond_yield_spread(FV,c,T,rate,intensities,R,freq=4,t=0,freq2=0,y0=0.0,**options): r""" Parameters: ---------- `FV` : float,int face value of the (risky) bond `c` : float annual coupon rate `rate`: float, int or tuple of lists Represents the zero-rate curve Returns: -------- `y2`: the non-risky bond yield `y1`: the risky bond yield `y2` - `y1`: the credit spread (`s`) """ from risky_bond_prices2 import risky_bond_price from bond_duration import bond_yield price1 = risky_bond_price(FV,c,T,rate,intensities,R,freq,t,freq2) price2 = risky_bond_price(FV,c,T,rate,0,R,freq,t,freq2) y1 = bond_yield(FV,c,T,rate,freq,t,freq2,price1,y0) y2 = bond_yield(FV,c,T,rate,freq,t,freq2,price2,y0) return y2,y1,y1-y2
def test_yield_bond2(): import numpy as np FV = 100 rates = ([1/12,2/12,3/12,6/12,9/12,1,2,3],[x/100 for x in [0.5,0.7,1.2,\ 1.4,1.7,2.1,2.3,2.5]]) coupons = [0, 0, 0, 0.04, 0.04, 0.06, 0.06, 0.08] freqs = [1, 1, 1, 2, 2, 4, 4, 2] times = rates[0] afp = [ bond_price(FV, coupons[i], times[i], rates, freqs[i]) for i in range(len(freqs)) ] "afp = arbitrage free prices" mkt_prices = [98.5, 99, 99.5, 100.5, 101.7, 102.5, 104.5, 105.5] yields = [ bond_yield(FV, coupons[i], times[i], rates, freqs[i]) for i in range(len(freqs)) ] yields2 = [bond_yield(FV,coupons[i],times[i],rates,freqs[i],0,0,mkt_prices[i]\ ) for i in range(len(freqs))] durations = [bond_duration(FV,coupons[i],times[i],mkt_prices[i],freqs[i]) \ for i in range(len(freqs))] durations2 = [bond_duration(FV,coupons[i],times[i],afp[i],freqs[i])\ for i in range(len(freqs))] modified_durations = [bond_duration(FV,coupons[i],times[i],mkt_prices[i],freqs[i],\ 0,1,Modified = 'YES') for i in range(len(freqs))] modified_durations2 = [bond_duration(FV,coupons[i],times[i],afp[i],freqs[i],\ 0,1,Modified = 'YES') for i in range(len(freqs))] print(durations) print(durations2) print(modified_durations) print(modified_durations2)
def bond_price_test5(): FV = 100 rates = ([1/12,2/12,3/12,6/12,9/12,1,2,3],[x/100 for x in [0.5,0.7,1.2,\ 1.4,1.7,2.1,2.3,2.5]]) coupons = [0,0,0,0.04,0.04,0.06,0.06,0.08] freqs = [1,1,1,2,2,4,4,2] times = rates[0] afp = [bond_price(FV,coupons[i],times[i],rates,freqs[i]) for i in range(len(freqs))] "arbitrage free price" mkt_prices = [98.5,99,99.5,100.5,101.7,102.5,104.5,105.5] yields = [bond_yield(FV,coupons[i],times[i],rates,freqs[i]) for i in range(len(freqs))] yields2 = [bond_yield(FV,coupons[i],times[i],rates,freqs[i],0,0,mkt_prices[i]\ ) for i in range(len(freqs))] print("Arbitrage free prices:",afp) print("Treasury yields:",yields) print("Realized yields:",yields2)
def test_pricing_bond(): import numpy as np FV, c, freq = 100, 0.1, 4 print(bond_price(FV, c, 1, 0.05, freq)) print( bond_yield(FV, c, 1, ([0.25, 0.5, 0.75, 1], [0.02, 0.03, 0.04, 0.05]), freq))
def test_yield_bond3(): FV = 100 rates = ([1/12,2/12,3/12,6/12,9/12,1,2,3],[x/100 for x in [0.5,0.7,1.2,\ 1.4,1.7,2.1,2.3,2.5]]) coupons = [0, 0, 0, 0.04, 0.04, 0.06, 0.06, 0.08] freqs = [1, 1, 1, 2, 2, 4, 4, 2] times = rates[0] afp = [ bond_price(FV, coupons[i], times[i], rates, freqs[i]) for i in range(len(freqs)) ] "afp = arbitrage free prices" mkt_prices = [98.5, 99, 99.5, 100.5, 101.7, 102.5, 104.5, 105.5] yields = [ bond_yield(FV, coupons[i], times[i], rates, freqs[i]) for i in range(len(freqs)) ] yields2 = [bond_yield(FV,coupons[i],times[i],rates,freqs[i],0,0,mkt_prices[i]\ ) for i in range(len(freqs))] durations = [bond_duration(FV,coupons[i],times[i],mkt_prices[i],freqs[i]) \ for i in range(len(freqs))] durations2 = [bond_duration(FV,coupons[i],times[i],afp[i],freqs[i])\ for i in range(len(freqs))] modified_durations = [bond_duration(FV,coupons[i],times[i],mkt_prices[i],freqs[i],\ 0,1,Modified = 'YES') for i in range(len(freqs))] modified_durations2 = [bond_duration(FV,coupons[i],times[i],afp[i],freqs[i],\ 0,1,Modified = 'YES') for i in range(len(freqs))] d = {'Zero rates':rates[1],'No-arb prices':afp,'Market price':mkt_prices,\ 'Treasury yields':yields,'Implied yields':yields2} d2 = {'No-arb prices':afp,'Duration':durations2,'Modified duration':modified_durations2,\ 'Market price':mkt_prices,'Implied duration':durations,\ 'Implied modified duration':modified_durations} import pandas as pd #new_index = pd.DataFrame.set_index(['1M','2M','3M','6M','9M','1Y','2Y','3Y']) indexes = ['1M', '2M', '3M', '6M', '9M', '1Y', '2Y', '3Y'] df = pd.DataFrame(data=d) df.index = indexes df2 = pd.DataFrame(data=d2) df2.index = indexes print(df) writer = pd.ExcelWriter('output.xlsx') df.to_excel(writer, 'Sheet1') df2.to_excel(writer, 'Sheet2') writer.save()
def test_yield(): FV, c, freq = 100, 0.05, 4 import numpy as np mkt_prices = np.linspace(98, 105, 15, endpoint=True) lifetimes = np.linspace(0.25, 3.75, 15, endpoint=True) yields = [bond_yield(FV,c,lifetimes[i],0,freq,0,mkt_prices[i])\ for i in range(len(lifetimes))] import matplotlib.pyplot as plt plt.plot(lifetimes, [yields[i] for i in range(len(lifetimes))]) plt.xlabel('Maturity') plt.ylabel('Yield') plt.title('Yield curve from Market prices') plt.grid(True) print(yields)
def test_bond_yield(): FV, c, T, freq = 100, 0.06, 2, 2 import numpy as np import matplotlib.pyplot as plt e1,e2,e3,e4 = np.array([1,0.5,0.2,0]),np.array([0,1,0.5,0.2]),np.array([0.2,0,1,0.5]),\ np.array([1,0,0,0.2]) rate = (np.array([0.5, 1, 1.5, 2]), np.array([0.035, 0.04, 0.055, 0.06])) g1 = lambda x: bond_yield(FV, c, T, (rate[0].tolist(), (rate[1] + x * e1).tolist()), freq) g2 = lambda x: bond_yield(FV, c, T, (rate[0].tolist(), (rate[1] + x * e2).tolist()), freq) g3 = lambda x: bond_yield(FV, c, T, (rate[0].tolist(), (rate[1] + x * e3).tolist()), freq) g4 = lambda x: bond_yield(FV, c, T, (rate[0].tolist(), (rate[1] + x * e4).tolist()), freq) div = np.linspace(0.001, 0.05, 50, endpoint=True) plt.subplot(221) plt.suptitle('Influence of component-wise shifts') plt.plot(div * 100, [g1(x) * 100 for x in div]) plt.xlabel('change in r1 (%)') plt.ylabel('Bond yield(%)') plt.grid(True) plt.subplot(222) plt.plot(div * 100, [g2(x) * 100 for x in div]) plt.xlabel('change in r2 (%)') plt.ylabel('Bond yield(%)') plt.grid(True) plt.subplot(223) plt.plot(div * 100, [g3(x) * 100 for x in div]) plt.xlabel('change in r3 (%)') plt.ylabel('Bond yield(%)') plt.grid(True) plt.subplot(224) plt.plot(div * 100, [g4(x) * 100 for x in div]) plt.xlabel('change in r4 (%)') plt.ylabel('Bond yield(%)') plt.grid(True)
def test_yield_zero_curve(): rates = ([x / 12 for x in [1, 2, 3, 6, 9, 12]], [x / 100 for x in [0.5, 1, 1.5, 2, 2.5, 3]]) FV, c, freq = 100, 0.24, 12 yields = [ bond_yield(FV, c, rates[0][i], rates, freq) for i in range(len(rates[1])) ] print(rates[0]) import numpy as np f1 = lambda x: np.interp(x, rates[0], rates[1]) f2 = lambda x: np.interp(x, rates[0], yields) import matplotlib.pyplot as plt div = np.linspace(0, 2, 21, endpoint=True) plt.plot(div, [f1(x) * 100 for x in div], label='zero-rate curve') plt.plot(div, [f2(x) * 100 for x in div], label='treasury yield curve') plt.xlabel('time (years)') plt.ylabel('zero/yield curve (%)') plt.title('Treasury yield curve vs. zero-rate curve') plt.grid(True) plt.legend()
def test_yield_bond1(): import numpy as np FV = 100 rates = ([1/12,2/12,3/12,6/12,9/12,1,2,3],[x/100 for x in [0.5,0.7,1.2,\ 1.4,1.7,2.1,2.3,2.5]]) coupons = [0, 0, 0, 0.04, 0.04, 0.06, 0.06, 0.08] freqs = [1, 1, 1, 2, 2, 4, 4, 2] times = rates[0] afp = [ bond_price(FV, coupons[i], times[i], rates, freqs[i]) for i in range(len(freqs)) ] "afp = arbitrage free prices" mkt_prices = [98.5, 99, 99.5, 100.5, 101.7, 102.5, 104.5, 105.5] yields = [ bond_yield(FV, coupons[i], times[i], rates, freqs[i]) for i in range(len(freqs)) ] yields2 = [bond_yield(FV,coupons[i],times[i],rates,freqs[i],0,0,mkt_prices[i]\ ) for i in range(len(freqs))] f = lambda x, i: (np.array(rates[1]) + x * np.eye(1, 8, i)).tolist()[0] g = lambda x: (np.array(rates[1]) + x * np.ones((1, 8))).tolist()[0] yields3 = [bond_yield(FV,coupons[i],times[i],(rates[0],g(0.001)),freqs[i]\ ) for i in range(len(freqs))] yields4 = [bond_yield(FV,coupons[i],times[i],(rates[0],f(0.005,0)),freqs[i]\ ) for i in range(len(freqs))] yields5 = [bond_yield(FV,coupons[i],times[i],(rates[0],f(0.005,7)),freqs[i]\ ) for i in range(len(freqs))] import matplotlib.pyplot as plt my_xticks = ['1', '2', '3', '6', '9', '12', '24', '36'] plt.figure(1) plt.xticks(rates[0], my_xticks) plt.plot(rates[0], np.array(yields) * 100, 'go--', label='Treasury yield curve') plt.plot(rates[0], np.array(yields3) * 100, 'ro--', label='Treasury yield curve: + 10bs') plt.title('Parallel shift of the treasury curve') plt.xlabel('Maturity (months)') plt.ylabel('Yield (treasury)') plt.legend() plt.grid(True) plt.show() plt.figure(2) plt.xticks(rates[0], my_xticks) plt.plot(rates[0], np.array(yields) * 100, 'go--', label='Treasury yield curve') plt.plot(rates[0], np.array(yields4) * 100, 'ro--', label='Treasury yield curve: + 50bs') plt.title('1M rate increase with 50 bps') plt.xlabel('Maturity (months)') plt.ylabel('Yield (treasury)') plt.legend() plt.grid(True) plt.show() plt.figure(3) plt.xticks(rates[0], my_xticks) plt.plot(rates[0], np.array(yields) * 100, 'go--', label='Treasury yield curve') plt.plot(rates[0], np.array(yields5) * 100, 'ro--', label='Treasury yield curve: + 50bs') plt.title('3Y rate increase with 50 bps') plt.xlabel('Maturity (months)') plt.ylabel('Yield (treasury)') plt.legend() plt.grid(True) plt.show()
1, 0.5, freq2=1, option="clean price")) print( bond_price(100, 0.06, 3, ([1, 2, 3], [0.08, 0.09, 0.1]), 1, 0.5, freq2=1, option="dirty price")) print( bond_yield(100, 0.06, 3, ([1, 2, 3], [0.08, 0.09, 0.1]), 1, freq2=1, y0=0.0)) #%% print(bond_yield(100, 0.05, 3, freq=1, freq2=1, mkt_price=100.65)) print(bond_yield(100, 0.02, 3, freq=1, freq2=1, mkt_price=100.25)) #%% print(bond_yield(100, 0.08, 10, freq=1, freq2=1, mkt_price=85.5030)) print(bond_price(100, 0.08, 9, 0.1040, freq=1, freq2=1)) #%% PV1 = 5 / 1.0305 + 5 / 1.0305**2 + 105 / 1.0305**3 PV2 = 5 / 1.0295 + 5 / 1.0295**2 + 105 / 1.0295**3 app_mod_dur = (PV2 - PV1) / (2 * 0.0005 * 105.657223) print(app_mod_dur) #%% x = 1 / (1 + 0.02)
def YTM(self, rate=None, t=0, freq2=0, mkt_price=None, y0=0.0, **options): return bond_yield(self.FV,self.c,self.T,rate,self.freq,t,freq2,\ mkt_price,y0,option = options.get("option"))