def price_CDS(FV, c, T, rate, intensities, R, freq=4, t=0, freq2=0): import numpy as np import scipy.integrate as integrate if isinstance(rate, (float, int)): discount = np.exp(-rate * (T - t)) f = lambda u: np.exp(-rate * (u - t)) if isinstance(intensities, (float, int)): surv = np.exp(-intensities * (T - t)) g = lambda u: np.exp(-intensities * (u - t)) * intensities h = lambda u: f(u) * g(u) elif isinstance(intensities, tuple) and all( isinstance(x, list) for x in intensities): model = piecewise_exponential(intensities[0], intensities[1]) surv = model.survival2(T - t) g = lambda u: model.pdf2(u - t) h = lambda u: f(u) * g(u) elif isinstance(rate, tuple) and all(isinstance(x, list) for x in rate): app_rate = np.interp(T - t, rate[0], rate[1]) discount = np.exp(-app_rate * (T - t)) f = lambda u: np.exp(-np.interp(u - t, rate[0], rate[1]) * (u - t)) if isinstance(intensities, (float, int)): surv = np.exp(-intensities * (T - t)) g = lambda u: np.exp(-(u - t) * intensities) * intensities h = lambda u: f(u) * g(u) elif isinstance(intensities, tuple) and all( isinstance(x, list) for x in intensities): model = piecewise_exponential(intensities[0], intensities[1]) surv = model.survival2(T - t) g = lambda u: model.pdf2(u - t) h = lambda u: f(u) * g(u) return FV*(discount*surv + integrate.quad(h,t,T)[0]) - \ risky_bond_price(FV,c,T,rate,intensities,R,freq,t,freq2)
def piece_expo(self, maturities, intensities, r=0, t0=0, RPV01=False, prob_dist=False): import numpy as np from piecewise_expo import piecewise_exponential T, R, freq = self.T, self.R, self.freq pe = piecewise_exponential(maturities, intensities) f = lambda t: pe.pdf2(t) S = lambda t: pe.survival2(t) D = lambda t: np.exp(-r * t) import scipy.integrate as integ q1 = integ.quad(lambda s: f(s) * D(s - t0) / S(t0) * (s > t0), t0, T)[0] if freq == 0: q2 = integ.quad(lambda s: S(s) * D(s - t0) / S(t0) * (s > t0), t0, T)[0] else: dt = 1 / freq times = [ x for x in np.linspace(1 / freq, T, int(T * freq)) if x > t0 ] q2 = dt * sum( [S(x) / S(t0) * np.exp(-r * (x - t0)) for x in times]) return (1 - R) * q1 / q2 if RPV01 == False else ((1 - R) * q1 / q2, q2)
def risky_bond_price4(FV,c,T,rates,intensities,R,freq=4,t=0,freq2=0): def times(t,T,freq = 4): r"The above function gives the times of cash-flows posterior to time t" 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) import numpy as np if t==T: return FV + (c/freq+1)*FV elif t>T or t<0: raise TypeError('the time when you want to evaluate the bond surpasses\ the lifetime of the bond or it is negative') else: import scipy.integrate as integrate time_points = times(t,T,freq) k = len(time_points) app_rates = [np.interp(time_points[i]-t,rates[0],rates[1])\ for i in range(k)] if freq2==0: disc_rates = [np.exp(-app_rates[i]*(time_points[i]-t)) for i in range(k)] else: disc_rates = [1/(1+app_rates[i]/freq2)**(freq2*(time_points[i]-t)) for i in range(k)] cash_flows = [c/freq*FV]*k cash_flows[-1]=cash_flows[-1]+FV model = piecewise_exponential(intensities[0],intensities[1]) survivs = [model.survival(time_points[i]-t) for i in range(len(time_points))] a = np.dot(np.array(disc_rates)*np.array(survivs),np.array(cash_flows)) f = lambda u: np.exp(-(u-t)*np.interp(u-t,rates[0],rates[1])) g = lambda u: model.pdf2(u-t) h = lambda u: f(u)*g(u) b = R*FV*integrate.quad(h,t,T,args=(),full_output = 1)[0] return a+b
def piece_expo_defer(self,maturities,intensities,r=0,t0=0,RPV01 = False\ ,T_reg_pmt=None,Tp = None): import numpy as np from piecewise_expo import piecewise_exponential FV, c, T, R, freq, B = self.FV, self.c, self.T, self.R, self.freq, self.B pe = piecewise_exponential(maturities, intensities) N = outstanding_notional(FV, c, T, freq, B) f = lambda t: pe.pdf2(t) S = lambda t: pe.survival2(t) D = lambda t: np.exp(-r * t) import scipy.integrate as integ q1 = integ.quad(lambda s: f(s) * D(s - t0) / S(t0) * (s > t0) * N(s), t0, T)[0] if freq == 0: q2 = integ.quad(lambda s:S(s)*D(s-t0)/S(t0)*(s>t0)*N(s),t0,T)[0] \ if T_reg_pmt==None and Tp == None else \ integ.quad(lambda s:S(s)*D(s-t0)/S(t0)*(s>t0)*N(s),t0,T_reg_pmt)[0]\ +S(Tp)/S(t0)*np.exp(-r*(Tp-t0)) else: dt = 1 / freq times = [x for x in np.linspace(1/freq,T_reg_pmt,\ int(T_reg_pmt*freq)) if x>t0]+[Tp] if Tp!=None else \ [x for x in np.linspace(1/freq,T_reg_pmt,int(T_reg_pmt*freq))\ if x>t0] q2 = dt * sum( [S(x) / S(t0) * np.exp(-r * (x - t0)) * N(x) for x in times]) return (1 - R) * q1 / q2
def pdf_exp(u): if isinstance(intensities, (float, int)): return intensities * np.exp(-intensities * (u - t)) elif isinstance(intensities, tuple) and all( isinstance(x, list) for x in intensities): model = piecewise_exponential(intensities[0], intensities[1]) return model.pdf2(u - t)
def test_class_piece(): b1 = piecewise_exponential([0.2, 0.3, 0.4], [1, 2]) x = b1.rvs2(10000) count = sum([(x[i] < 2) * 1 for i in range(len(x))]) / len(x) count2 = sum([(x[i] < 1) * 1 for i in range(len(x))]) / len(x) print(count) import numpy as np print(1 - np.exp(-0.5)) print(count2, 1 - np.exp(-0.2))
def price_LtD_swap3(FV1,FV2,c,T,rate,intensities1,intensities2,R1,R2,freq = 4,t=0,freq2 = 0): import numpy as np import scipy.integrate as integrate def times(t,T,freq): if freq*(T-t)==int(freq*(T-t)): k = freq*(T-t)-1 else: k = int(freq*(T-t)) return np.linspace(T-k/freq,T,(k+1),endpoint = True) h = 1/freq time_points = times(t,T,freq) from piecewise_expo import piecewise_exponential model1 = piecewise_exponential(intensities1[0],intensities1[1]) model2 = piecewise_exponential(intensities2[0],intensities2[1]) def surv_ltd(u): return 1-model1.cdf2(u-t)*model2.cdf(u-t) def pdf_ltd(u): return model1.pdf2(u-t)*model2.cdf(u-t)+model1.cdf2(u-t)*model2.pdf2(u-t) def discount(u): if isinstance(rate,(float,int)): if freq2==0: return np.exp(-rate*(u-t)) else: return 1/(1+rate/freq2)**(freq2*(u-t)) elif isinstance(rate,tuple) and all(isinstance(x,list) for x in rate): app_rate = np.interp(u-t,rate[0],rate[1]) if freq2==0: return np.exp(-app_rate*(u-t)) else: return 1/(1+app_rate/freq2)**(freq2*(u-t)) def RPV01(): survivs = [surv_ltd(u) for u in time_points] discounts = [discount(u) for u in time_points] return h*np.dot(survivs,discounts) fct1 = lambda y: model1.cdf2(y) * model1.pdf2(y) proba = integrate.quad(fct1,0,np.Inf)[0] fct2 = lambda u:discount(u)*pdf_ltd(u) discounted_leg = ((1-R2)*FV2*proba + (1-R1)*FV1*(1-proba))*integrate.quad(fct2,t,T)[0] premium_leg = c*(FV2*proba + FV1*(1-proba))*RPV01() return discounted_leg - premium_leg
def test_expo_dist(): f = stats.expon print(f.cdf(1, loc=0, scale=1 / 1.1)) g = piecewise_exponential([0.5, 1], [0.2, 0.3, 0.4]) print(g.cdf(1))
def test_class_piece2(): b1 = piecewise_exponential([1, 2, 3, 4], [0.2, 0.3, 0.4, 0.7, 0.9]) print(b1.survival(1), b1.survival(2)) print(b1.survival2(1), b1.survival2(2)) print(b1.survival(4.1)) print(b1.survival2(4.1))