def bond_price_test6(): "Price sensitivities for two money market instruments" FV,T1,T2 = 100,0.25,10 r,freq = 0.025,2 c1,c2 = 0,0.08 px1 = bond_price(FV,c1,T1,r,freq) px2 = bond_price(FV,c2,T2,r,freq) f1,f2 = lambda x:bond_price(FV,c1,T1,r+x,freq),lambda x:bond_price(FV,c2,T2,r+x,freq) import numpy as np import matplotlib.pyplot as plt div = np.linspace(0,0.1,51,endpoint = True) fig, ax1 = plt.subplots() color1,color2 = 'tab:red','tab:green' ax1.set_xlabel('$\Delta r$ (%)') ax1.set_ylabel('$\Delta$ price (%) 3M treasury bill') ln1 = ax1.plot(div*100,[(f1(x)/px1 - 1)*100 for x in div],\ label ='Treasury bill 3M % price change' ,color = color1) ax1.grid() ax2 = ax1.twinx() ax2.set_ylabel('$\Delta$ price (%) 10Y bond') ln2 = ax2.plot(div*100,[(f2(x)/px2 - 1)*100 for x in div],\ label = 'Bond 10Y % price change',color = color2) lns = ln1+ln2 labs = [l.get_label() for l in lns] ax1.legend(lns,labs,loc = 0) plt.title('% change in instrument price') plt.grid(True) fig.tight_layout() plt.show()
def IRS_price(FV, c, T, rate, libor, freq=4, t=0, freq2=0, option='floating payer'): r""" Description: ----------- This function builds the price of an interest rate swap. """ p1 = bond_price(FV, c, T, rate, freq, t, freq2) def times(t, T, freq): if freq * (T - t) == int(freq * (T - t)): k = freq * (T - t) - 1 else: k = int(freq * (T - t)) import numpy as np return np.linspace(T - k / freq, T, (k + 1), endpoint=True) time_points = times(t, T, freq) p2 = bond_price(FV, libor, time_points[0] - t, rate, freq, 0, freq2) return p1 - p2
def bond_price_test4(): import matplotlib.pyplot as plt import numpy as np FV,c,T,freq,rate = 100,0.06,2,2,(np.array([0.5,1,1.5,2]),np.array([0.05,0.058,0.064,0.068])) e1,e2,e3,e4 = np.array([1,0,0,0]),np.array([0,1,0,0]),np.array([0,0,1,0]),\ np.array([0,0,0,1]) g1 = lambda x:bond_price(FV,c,T,(rate[0].tolist(),(rate[1]+x*e1).tolist()),freq) g2 = lambda x:bond_price(FV,c,T,(rate[0].tolist(),(rate[1]+x*e2).tolist()),freq) g3 = lambda x:bond_price(FV,c,T,(rate[0].tolist(),(rate[1]+x*e3).tolist()),freq) g4 = lambda x:bond_price(FV,c,T,(rate[0].tolist(),(rate[1]+x*e4).tolist()),freq) prix = bond_price(FV,c,T,(rate[0].tolist(),rate[1].tolist()),freq) div = np.linspace(0.001,0.02,20,endpoint = True) plt.subplot(221) plt.suptitle('Influence of component-wise shifts') plt.plot(div*100,[(g1(x)/prix-1)*100 for x in div]) plt.xlabel('change in r1 (%)') plt.ylabel('Bond price % change') plt.grid(True) plt.subplot(222) plt.plot(div*100,[(g2(x)/prix-1)*100 for x in div]) plt.xlabel('change in r2 (%)') plt.ylabel('Bond price % change') plt.grid(True) plt.subplot(223) plt.plot(div*100,[(g3(x)/prix-1)*100 for x in div]) plt.xlabel('change in r3 (%)') plt.ylabel('Bond price % change') plt.grid(True) plt.subplot(224) plt.plot(div*100,[(g4(x)/prix-1)*100 for x in div]) plt.xlabel('change in r4 (%)') plt.ylabel('Bond price % change') plt.grid(True)
def bond_price_test3(): import matplotlib.pyplot as plt import numpy as np FV,c,T,freq,rates = 100,0.06,2,2,([0.5,1,1.5,2],[0.05,0.058,0.064,0.068]) prix = bond_price(FV,c,T,rates,freq) fct = lambda x:[z+x for z in rates[1]] div = np.linspace(0.001,0.02,20,endpoint = True) f = lambda x:bond_price(FV,c,T,(rates[0],fct(x)),freq) plt.figure(1) plt.plot(div*100,[(f(x)/prix-1)*100 for x in div]) plt.xlabel('Parallel shift in curve (%)') plt.ylabel('Bond price (%) change') plt.title('Parallel shift') plt.grid(True) plt.show()
def test_bond_price3(): "evolution with lifetime for two coupons" FV, freq, r = 100, 2, 0.04 f = lambda T: bond_price(FV, 0.06, T, r, freq) g = lambda T: bond_price(FV, 0.08, T, r, freq) import numpy as np div = np.linspace(0.5, 30, 60, endpoint=True) import matplotlib.pyplot as plt plt.plot(div, [f(x) for x in div], label='coupon: 6%') plt.plot(div, [g(x) for x in div], label='coupon: 8%') plt.xlabel('Lifetime (years)') plt.ylabel('Bond price') plt.title('Bond price dependence on lifetime') plt.legend() plt.grid(True)
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 test2(): from risky_bond_prices import risky_bond_price from bond_prices import bond_price FV, c, T, lbd, R, freq = 100, 0.045, 10, 0, 0.4, 1 rate = ([0.5, 1, 1.5, 2], [0.05, 0.05, 0.05, 0.05]) print(risky_bond_price(FV, c, T, rate, lbd, R, freq)) print(bond_price(FV, c, T, rate, freq))
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 bootstrap2(face_values, coupons, lifetimes, times, freqs, bond_prix, t=0, freq2=0, y0=None): r""" Description: --------------------- Fitting the zero-curve to bond market prices. This is not bootstrapping. Details: --------------------- The number of available bond prices is greater than the parameters to be calibrated The entire zero-curve is to be determined. Remarks: -------- For partial bootstrapping, please refer to bootstrap3 function. """ from bond_prices import bond_price f = lambda r:[bond_price(face_values[i],coupons[i],lifetimes[i],\ (times,r.tolist()),freqs[i],t,freq2) - bond_prix[i] for i in range(len(face_values))] if y0 == None: y0 = np.array([0] * len(times)) res = optim.least_squares(f, y0) return res.x, res.cost else: res = optim.least_squares(f, y0) return res.x, res.cost
def CDS_price_test2(): from nelson_siegel_curve import nelson_siegel_curve theta1,theta2,theta3,theta4 = 0.05,-0.05,0.06,10 curve = nelson_siegel_curve(theta1,theta2,theta3,theta4) c=0.05 freq=1 print(bond_price(100,c,1,curve.rate(1),freq))
def bootstrap1_test(): r""" This is an example of bootstrapping 2 zero rates from 2 bond prices """ FV,c1,c2,rates,T,freq = 100,0.06,0.08,([0.5,1],[0.04,0.06]),1,2 from bond_prices import bond_price prix1 = bond_price(FV,c1,T,rates,freq) prix2 = bond_price(FV,c2,T,rates,freq) print(prix1,prix2) f = lambda r:[3*np.exp(-r[0]/2)+103*np.exp(-r[1])-99.5,4*np.exp(-r[0]/2)+104*np.exp(-r[1])-101.5] g = [lambda r:bond_price(FV,c1,T,(rates[0],r.tolist()),freq), \ lambda r:bond_price(FV,c2,T,(rates[0],r.tolist()),freq)] l = optim.fsolve(f,np.zeros((1,2))) l2 = optim.fsolve(g,np.array([0,0])) print(l,type(l)) print(l2) print(bond_price(FV,c1,T,([0.5,1],l.tolist()),freq))
def bond_price_test7(): FV,T1,T2 = 100,0.25,10 r,freq = 0.025,2 c1,c2 = 0,0.08 px1 = bond_price(FV,c1,T1,r,freq) px2 = bond_price(FV,c2,T2,r,freq) f1,f2 = lambda x:bond_price(FV,c1,T1,r+x,freq),lambda x:bond_price(FV,c2,T2,r+x,freq) import numpy as np import matplotlib.pyplot as plt div = np.linspace(0,0.1,51,endpoint = True) plt.plot(div*100,[(f1(x)/px1 - 1)*100 for x in div],label = 'Treasury bill 3M % price change' ) plt.plot(div*100,[(f2(x)/px2 - 1)*100 for x in div],label = 'Bond 10Y % price change') plt.title('% price change of instruments') plt.xlabel('$\Delta r$ (%)') plt.ylabel('$\Delta$ price (%)') plt.grid(True) plt.legend() plt.show()
def bootstrap1(face_values, coupons, lifetimes, times, freqs, bond_prix, t=0, freq2=0, y0=None): r""" Description: -------------- Complete bootstrapping. This function finds the zero rates when the number of unknowns is exactly the number of market prices we have at disposal. Parameters: ---------- `face_values`: list Face values for the bonds whose prices are given `coupons`: list Annual coupon rates for the bonds whose prices are given `lifetimes`: list The lifetimes of the existing bonds/Money Market Instruments existing `times`: list Represents the times for which we find the corresponding zero rates `freqs`: list frequences of payments `bond_prix`: list Market bond prices from where the bootstrapping is started For the case when the number of available data is bigger than the parameters to be found, please refer to bootstrap2 function. """ from bond_prices import bond_price f = lambda r:[bond_price(face_values[i],coupons[i],lifetimes[i],\ (times,r.tolist()),freqs[i],t,freq2) - bond_prix[i] \ for i in range(len(face_values))] if y0 == None: y0 = np.zeros((1, len(face_values))) return optim.fsolve(f, y0) else: return optim.solve(f, np.array(y0))
def bond_option_price(TTM_bond,FV,c,freq,TTM_opt,K_opt,sig_y,rates,option = "call"): import numpy as np cash_price = bond_price(FV,c,TTM_bond,rates,freq) k = int(TTM_opt * freq) cash_flows = [c*FV/freq]*k times = np.linspace(1/freq,k/freq,k) bp = bond_price(FV,c,TTM_bond,rates,freq,t = TTM_opt) duration = bond_duration(FV,c,TTM_bond,mkt_price = bp,freq = freq,t=TTM_opt ) if isinstance(rates,(int,float)): disc_rates = [np.exp(-times[i]*rates) for i in range(k)] sig_bond = sig_y * duration * rates PV_interest = np.dot(cash_flows,[disc_rates[i] for i in range(k)]) fwd_price_bond = (cash_price - PV_interest)*np.exp(TTM_opt * rates) elif isinstance(rates,tuple) and [isinstance(rates[i],list) for i in range(len(rates))]: rate = lambda x:np.interp(x,rates[0],rates[1]) disc_rates = [np.exp(-times[i]*rate(times[i])) for i in range(k)] sig_bond = sig_y * duration * rates[0][0] PV_interest = np.dot(cash_flows,[disc_rates[i] for i in range(k)]) fwd_price_bond = (cash_price - PV_interest)*np.exp(TTM_opt * rate(TTM_opt)) return bop_black(rates,TTM_opt,K_opt,fwd_price_bond,sig_bond,option)
def test_bond_price2(): FV, T, freq = 100, 2, 2 f = lambda x: bond_price(FV, 0.04, T, x, freq) g = lambda x: bond_price(FV, 0.08, T, x, freq) import numpy as np div = np.linspace(0, 0.2, 21, endpoint=True) import matplotlib.pyplot as plt plt.suptitle('Bond price dependence on flat interest rate') plt.subplot(121) plt.plot(div * 100, [f(x) for x in div], label='coupon: 4%') plt.plot(div * 100, [g(x) for x in div], label='coupon: 8%') plt.xlabel('interest rate (%)') plt.ylabel('bond price ') plt.legend() plt.grid(True) plt.subplot(122) plt.plot(div, [f(x) - g(x) for x in div]) plt.xlabel('interest rate (%)') plt.ylabel('difference') plt.grid(True)
def test_bond_class(): b1 = bond(100, 0.06, 2, 2) rate = ([0.5, 1, 1.5, 2], [0.05, 0.058, 0.064, 0.068]) print(b1.price(rate)) print(bond_price(100, 0.06, 2, rate, 2)) print(b1.YTM(rate, 0, 0)) print(b1.duration(None, 0, 0, 0, rate)) b2 = bond(100, 0, 2, 2) print(b2.duration(None, 0, 0, 0, rate)) b3 = bond(100, 0.1, 3, 2) print(b3.duration(None, 0, 0, 0, 0.12))
def bond_price_test2(): import matplotlib.pyplot as plt import numpy as np FV,c,T,freq = 100,0.06,2,2 f = lambda r: bond_price(FV,c,T,r,freq) div = np.linspace(-0.02,0.1,61,endpoint = True) plt.plot(div*100,[f(x) for x in div],'b--') plt.xlabel('Flat interest rate (%)') plt.ylabel('Bond price') plt.title('Bond price evolution with interest rate') plt.grid(True)
def test_bond_price1(): "Flat interest rate" FV, c, T, freq = 100, 0.04, 2, 2 f = lambda x: bond_price(FV, c, T, x, freq) g = lambda x: bond_price(FV, c, T, x, 4) import numpy as np div = np.linspace(0, 0.2, 21, endpoint=True) import matplotlib.pyplot as plt plt.suptitle('Bond price dependence on flat interest rate') plt.subplot(121) plt.plot(div * 100, [f(x) for x in div], label='frequence: semi-annually') plt.plot(div * 100, [g(x) for x in div], label='frequence: quarterly') plt.xlabel('interest rate (%)') plt.ylabel('bond price ') plt.legend() plt.grid(True) plt.subplot(122) plt.plot(div, [f(x) - g(x) for x in div]) plt.xlabel('interest rate (%)') plt.ylabel('difference') plt.grid(True)
def implied_bop_vol2(rates,TTM_opt,K_opt,mkt_price,TTM_bond,FV,c,freq,option = "call",\ a0 = 0.0,b0 = 1.0,niters = 30,tol = 0.0001): import numpy as np bp = bond_price(FV,c,TTM_bond,rates,freq,t = TTM_opt) duration = bond_duration(FV,c,TTM_bond,mkt_price = bp,freq = freq,t=TTM_opt ) cash_price = bond_price(FV,c,TTM_bond,rates,freq) k = int(TTM_opt * freq) cash_flows = [c*FV/freq]*k times = np.linspace(1/freq,k/freq,k) if isinstance(rates,(int,float)): y0 = rates disc_rates = [np.exp(-times[i]*rates) for i in range(k)] PV_interest = np.dot(cash_flows,[disc_rates[i] for i in range(k)]) fwd_price_bond = (cash_price - PV_interest)*np.exp(TTM_opt * rates) elif isinstance(rates,tuple) and [isinstance(rates[i],list) for i in range(len(rates))]: y0 = rates[0][0] rate = lambda x:np.interp(x,rates[0],rates[1]) disc_rates = [np.exp(-times[i]*rate(times[i])) for i in range(k)] PV_interest = np.dot(cash_flows,[disc_rates[i] for i in range(k)]) fwd_price_bond = (cash_price - PV_interest)*np.exp(TTM_opt * rate(TTM_opt)) sig_B = implied_bop_vol(rates,TTM_opt,K_opt,fwd_price_bond,mkt_price,\ option = option,a0 = a0,b0 = b0,niters = niters,tol = tol)[0] return sig_B/(duration * y0)
def test_bond_price5(): 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,0,0]),np.array([0,1,0,0]),np.array([0,0,1,0]),\ np.array([0,0,0,1]) rate = (np.array([0.5, 1, 1.5, 2]), np.array([0.03, 0.04, 0.05, 0.06])) g1 = lambda x: bond_price(FV, c, T, (rate[0].tolist(), (rate[1] + x * e1).tolist()), freq) g2 = lambda x: bond_price(FV, c, T, (rate[0].tolist(), (rate[1] + x * e2).tolist()), freq) g3 = lambda x: bond_price(FV, c, T, (rate[0].tolist(), (rate[1] + x * e3).tolist()), freq) g4 = lambda x: bond_price(FV, c, T, (rate[0].tolist(), (rate[1] + x * e4).tolist()), freq) div = np.linspace(0.001, 0.02, 20, endpoint=True) plt.subplot(221) plt.suptitle('Influence of component-wise shifts') plt.plot(div * 100, [g1(x) for x in div]) plt.xlabel('change in r1 (%)') plt.ylabel('Bond price') plt.grid(True) plt.subplot(222) plt.plot(div * 100, [g2(x) for x in div]) plt.xlabel('change in r2 (%)') plt.ylabel('Bond price') plt.grid(True) plt.subplot(223) plt.plot(div * 100, [g3(x) for x in div]) plt.xlabel('change in r3 (%)') plt.ylabel('Bond price') plt.grid(True) plt.subplot(224) plt.plot(div * 100, [g4(x) for x in div]) plt.xlabel('change in r4 (%)') plt.ylabel('Bond price') plt.grid(True)
def test_bond_price4(): FV, c, T, freq = 100, 0.06, 2, 2 import numpy as np import matplotlib.pyplot as plt rate = (np.array([0.5, 1, 1.5, 2]), np.array([0.03, 0.04, 0.05, 0.06])) f = lambda x: bond_price(FV, c, T, (rate[0].tolist(), (rate[1] + x).tolist()), freq) div = np.linspace(0.001, 0.02, 20, endpoint=True) plt.figure(1) plt.plot(div * 100, [f(x) for x in div]) plt.xlabel('Parallel shift in curve (%)') plt.ylabel('Bond price') plt.title('Parallel shift') plt.grid(True) plt.show()
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_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_bond_price_comp(): FV, c, T, freq, y, chg1, chg2 = 100, 0.08, 5, 1, 0.11, -0.002, -0.01 prix = bond_price(FV, c, T, y, freq) dur = bond_duration(FV, c, T, prix, freq) prix2 = prix * (1 - dur * chg1) conv = bond_convexity(FV, c, T, prix, freq) prix2bis = bond_price(FV, c, T, y + chg1, freq) print("==============") print("Continuous compounding:\n===============") print("The duration is", dur) print("The initial price is", prix) print("The duration price after a 0.2% decrease in yield", prix2) print("The actual price after a 0.2% decrease in yield", prix2bis) prix3 = prix * (1 - dur * chg2) prix3bis = prix * (1 - dur * chg2 + 1 / 2 * conv * chg2**2) prix3bisbis = bond_price(FV, c, T, y + chg2, freq) print("After a 1% decrease in yield, the duration price is", prix3) print("After a 1% decrease in yield, the dur-conv price is", prix3bis) print("After a 1% decrease in yield, the actual price is", prix3bisbis) print("===============") prix_ann = bond_price(FV, c, T, y, freq, 0, 1) dur2 = bond_duration(FV, c, T, prix_ann, freq, 0, 1, Modified='Yes') prix_ann2 = prix_ann * (1 - dur2 * chg1) prix_ann2bis = bond_price(FV, c, T, y + chg1, freq, 0, 1) print("Yearly compounding:\n===============") print("The modified duration is:", dur2) print("The initial price is:", prix_ann) print("The duration price after a 0.2% decrease in yield", prix_ann2) print("The actual price after a 0.2% decrease in yield", prix_ann2bis) conv2 = bond_convexity(FV, c, T, prix_ann, freq, 0, 1) prix4 = prix_ann * (1 - dur2 * chg2) prix4bis = prix_ann * (1 - dur2 * chg2 + 1 / 2 * conv2 * chg2**2) prix4bisbis = bond_price(FV, c, T, y + chg2, freq, 0, 1) print("After a 1% decrease in yield, the duration price is", prix4) print("After a 1% decrease in yield, the dur-conv price is", prix4bis) print("After a 1% decrease in yield, the actual price is", prix4bisbis)
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()
def bootstrap2_test(): FV,c1,c2,rates,T,freq = 100,0.06,0.08,([0.5,1],[0.04,0.06]),1,2 from bond_prices import bond_price g = lambda r: [bond_price(FV,c1,T,(rates[0],r),freq),bond_price(FV,c2,T,(rates[0],r),freq)] print(g([0.04,0.06]))
def bond_price_test1(): FV,c,T,freq,r = 100,0.06,2,2,0.0676 print(bond_price(FV,c,T,r,freq)) print(bond_price(FV,c,T,r,freq,0,1)) print(bond_price(FV,c,T,r,freq,0,2))
def price(self, rate, t=0, freq2=0, **options): return bond_price(self.FV,self.c,self.T,rate,self.freq,t,freq2,\ option = options.get("option"))
# -*- coding: utf-8 -*- """ Created on Sat Apr 27 11:47:19 2019 @author: Theodor """ from bond_prices import bond_price from bond_duration import bond_yield, bond_duration #%% print(bond_price(100, 0.08, 3, ([1, 2, 3], [0.08, 0.09, 0.1]), 1, freq2=1)) print(bond_price(100, 0.07, 3, ([1, 2, 3], [0.08, 0.09, 0.1]), 1, freq2=1)) print( bond_price(100, 0.06, 3, ([1, 2, 3], [0.08, 0.09, 0.1]), 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,