diff options
| -rw-r--r-- | python/analytics/basket_index.py | 2 | ||||
| -rw-r--r-- | python/analytics/tranche_basket.py | 28 |
2 files changed, 19 insertions, 11 deletions
diff --git a/python/analytics/basket_index.py b/python/analytics/basket_index.py index 1e241226..8bf5a8a2 100644 --- a/python/analytics/basket_index.py +++ b/python/analytics/basket_index.py @@ -46,7 +46,7 @@ class BasketIndex(CreditIndex): "ORDER BY lastdate", (index_type, series)) self._version = tuple(tuple(t) for t in r) self.issue_date = self.index_desc.issue_date[0] - maturities = self.index_desc.maturity.sort_values().dt.to_pydatetime() + maturities = self.index_desc.maturity[tenors].sort_values().dt.to_pydatetime() self.index_desc = self.index_desc.reset_index().set_index('maturity') curves, args = get_singlenames_curves(index_type, series, trade_date) _, jp_yc, _, step_in_date, value_date, _ = args diff --git a/python/analytics/tranche_basket.py b/python/analytics/tranche_basket.py index fbef179c..53514824 100644 --- a/python/analytics/tranche_basket.py +++ b/python/analytics/tranche_basket.py @@ -59,6 +59,9 @@ class TrancheBasket(BasketIndex): self._Z, self._w = GHquad(self._Ngh) self.rho = np.full(self.K.size, np.nan) + def tranche_factors(self): + return np.diff(self.K) / np.diff(self.K_orig) * self.factor + def _get_quotes(self): refprice = self.tranche_quotes.indexrefprice.iat[0] refspread = self.tranche_quotes.indexrefspread.iat[0] @@ -76,7 +79,8 @@ class TrancheBasket(BasketIndex): @property def default_prob(self): - return 1 - super().survival_matrix(self.cs.index.values.astype('M8[D]').view('int') + 134774) + sm, tickers = super().survival_matrix(self.cs.index.values.astype('M8[D]').view('int') + 134774) + return pd.DataFrame(1 - sm, index=tickers, columns=self.cs.index) def tranche_legs(self, K, rho, complement=False): if ((K == 0. and not complement) or (K == 1. and complement)): @@ -84,7 +88,7 @@ class TrancheBasket(BasketIndex): elif ((K == 1. and not complement) or (K == 0. and complement)): return self.index_pv()[:-1] else: - L, R = BCloss_recov_dist(self.default_prob, + L, R = BCloss_recov_dist(self.default_prob.values, self.weights, self.recovery_rates, rho, @@ -114,9 +118,9 @@ class TrancheBasket(BasketIndex): return cl, pl, bp def index_pv(self, discounted=True): - ELvec = (self.weights * (1 - self.recovery_rates) @ \ - self.default_prob) - size = 1 - self.weights @ self.default_prob + DP = self.default_prob.values + ELvec = self.weights * (1 - self.recovery_rates) @ DP + size = 1 - self.weights @ DP sizeadj = 0.5 * (np.hstack((1., size[:-1])) + size) if not discounted: pl = - ELvec[-1] @@ -133,9 +137,9 @@ class TrancheBasket(BasketIndex): def tranche_deltas(self, complement=False): eps = 1e-4 - self._N = 301 + self._Ngrid = 301 index_list = [self] - for tweak in eps, -eps, 2*eps: + for tweak in [eps, -eps, 2*eps]: tb = deepcopy(self) tb.tweak_portfolio(tweak, self.maturity) index_list.append(tb) @@ -144,10 +148,14 @@ class TrancheBasket(BasketIndex): for i, index in enumerate(index_list): indexbp[i] = index.index_pv()[2] bp[i] = index.tranche_pvs(complement)[2] - deltas = (bp[1] - bp[2]) / (indexbp[1]-indexbp[2]) - deltasplus = (bp[3] - bp[0]) / (indexbp[3]-indexbp[0]) + + deltas = (bp[1] - bp[2]) / (indexbp[1] - indexbp[2]) * self.tranche_factors() / self.factor + deltasplus = (bp[3] - bp[0]) / (indexbp[3]-indexbp[0]) * self.tranche_factors() / self.factor gammas = (deltasplus - deltas) / (indexbp[1] - indexbp[0]) / 100 - return deltas, gammas + return pd.DataFrame({'delta': deltas, 'gamma': gammas}, + index=self.tranche_quotes[['attach', 'detach']]. + apply(lambda row: f'{row.attach}-{row.detach}', + axis=1)) def build_skew(self, skew_type="bottomup"): assert(skew_type == "bottomup" or skew_type == "topdown") |
