def zbt_libor_yield(instruments, yields, pricing_date, basis='Actual/Actual (Bond)', compounding_freq='Continuous', maturity_dates=None): """ Bootstrap a zero-coupon curve from libor rates and swap yields Args: instruments: list of instruments, of the form Libor?M for Libor rates and Swap?Y for swap rates yields: market rates pricing_date: the date where market data is observed. Settlement is by default 2 days after pricing_date Optional: compounding_frequency: ... of zero-coupon rates. By default: 'Continuous' Returns: zero_rate: zero-coupon rate maturity_date: ... of corresponding rate """ calendar = TARGET() settings = Settings() # must be a business day eval_date = calendar.adjust(pydate_to_qldate(pricing_date)) settings.evaluation_date = eval_date rates = dict(zip(instruments, yields)) ts = make_term_structure(rates, pricing_date) cnt = DayCounter.from_name(basis) if maturity_dates is None: # schedule of maturity dates from settlement date to last date on # the term structure s = Schedule(effective_date=ts.reference_date, termination_date=ts.max_date, tenor=Period(1, Months), calendar=TARGET()) maturity_dates = [qldate_to_pydate(dt) for dt in s.dates()] cp_freq = Compounding[compounding_freq] zc = [ ts.zero_rate(pydate_to_qldate(dt), day_counter=cnt, compounding=cp_freq).rate for dt in maturity_dates ] return (maturity_dates, zc)
def zbt_libor_yield(instruments, yields, pricing_date, basis='Actual/Actual (Bond)', compounding_freq='Continuous', maturity_dates=None): """ Bootstrap a zero-coupon curve from libor rates and swap yields Args: insruments: list of instruments, of the form Libor?M for Libor rates and Swap?Y for swap rates yields: market rates pricing_date: the date where market data is observed. Settlement is by default 2 days after pricing_date Optional: compounding_frequency: ... of zero-coupon rates. By default: 'Continuous' Returns: zero_rate: zero-coupon rate maturity_date: ... of corresponding rate """ calendar = TARGET() settings = Settings() # must be a business day eval_date = calendar.adjust(pydate_to_qldate(pricing_date)) settings.evaluation_date = eval_date rates = dict(zip(instruments, yields)) ts = make_term_structure(rates, pricing_date) cnt = DayCounter.from_name(basis) if maturity_dates is None: # schedule of maturity dates from settlement date to last date on # the term structure s = Schedule(effective_date=ts.reference_date, termination_date=ts.max_date, tenor=Period(1, Months), calendar=TARGET()) maturity_dates = [qldate_to_pydate(dt) for dt in s.dates()] cp_freq = compounding_from_name(compounding_freq) zc = [ts.zero_rate(date=pydate_to_qldate(dt), day_counter=cnt, compounding=cp_freq).rate for dt in maturity_dates] return (maturity_dates, zc)
dtI = dtObs[range(0, len(dtObs) - 1, 60)] days = [ 10, 30, 90, 182, 365, 365 * 2, 365 * 3, 365 * 5, 365 * 10, 365 * 15 ] # maturity in columns, observation days in rows zc_rate = np.empty((len(dtI), len(days)), dtype='float64') dt_maturity = np.empty_like(zc_rate, dtype='object') # one observation date at a time, construct a term structure from # deposit and swap rates, then compute zero-coupon rates at # selected maturities for i, obs_date in enumerate(dtI): print(obs_date) rates = df_libor.xs(obs_date) / 100.0 ts = make_term_structure(rates, obs_date) (dt_maturity[i, ], zc_rate[i, ]) = zero_rate(ts, days, obs_date) # PCA on rate change zc_pca = ml.PCA(np.diff(zc_rate, axis=0)) fig = plt.figure() fig.set_size_inches(10, 6) ax = fig.add_subplot(121) dtMin = dt_maturity[0, 0] dtMax = dt_maturity[-1, -1] ax.set_xlim(dtMin, dtMax) ax.set_ylim(0.0, 0.1)
dtI = dtObs[range(0, len(dtObs) - 1, 60)] days = [10, 30, 90, 182, 365, 365 * 2, 365 * 3, 365 * 5, 365 * 10, 365 * 15] # maturity in columns, observation days in rows zc_rate = np.empty((len(dtI), len(days)), dtype='float64') dt_maturity = np.empty_like(zc_rate, dtype='object') # one observation date at a time, construct a term structure from # deposit and swap rates, then compute zero-coupon rates at # selected maturities for i, obs_date in enumerate(dtI): print(obs_date) rates = df_libor.xs(obs_date) / 100 ts = make_term_structure(rates, obs_date) (dt_maturity[i, ], zc_rate[i, ]) = zero_rate(ts, days, obs_date) # PCA on rate change zc_pca = ml.PCA(np.diff(zc_rate, axis=0)) fig = plt.figure() fig.set_size_inches(10, 6) ax = fig.add_subplot(121) dtMin = dt_maturity[0, 0] dtMax = dt_maturity[-1, -1] ax.set_xlim(dtMin, dtMax) ax.set_ylim(0.0, 0.1)