diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/analytics/tranche_basket.py | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/python/analytics/tranche_basket.py b/python/analytics/tranche_basket.py index d5398ffd..f710eb11 100644 --- a/python/analytics/tranche_basket.py +++ b/python/analytics/tranche_basket.py @@ -106,30 +106,32 @@ class DualCorrTranche(): @memoize(hasher=lambda args: (hash(args[0]._index), *args[1:])) def tranche_legs(self, K, rho, epsilon=0.): + Legs = namedtuple('TrancheLegs', 'coupon_leg, protection_leg, bond_price') if K == 0.: - return 0., 0. + return Legs(0., 0., 1.) elif K == 1.: - return self.index_pv()[:-1] + return Legs(*self.index_pv(epsilon)) elif rho == -1.: raise ValueError("ρ needs to be a real number between 0. and 1.") else: - Legs = namedtuple('TrancheLegs', 'coupon_leg, protection_leg') if self.use_trunc: EL, ER = BCloss_recov_trunc(self._default_prob(epsilon), self._index.weights, self._index.recovery_rates, rho, K, self._Z, self._w, self._Ngrid) - return Legs(tranche_cl_trunc(EL, ER, self.cs, 0., K), - tranche_pl_trunc(EL, self.cs, 0., K)) + cl = tranche_cl_trunc(EL, ER, self.cs, 0., K) + pl = tranche_pl_trunc(EL, self.cs, 0., K) else: L, R = BCloss_recov_dist(self._default_prob(epsilon), self._index.weights, self._index.recovery_rates, rho, self._Z, self._w, self._Ngrid) - return Legs(tranche_cl(L, R, self.cs, 0., K), - tranche_pl(L, self.cs, 0., K)) + cl = tranche_cl(L, R, self.cs, 0., K) + pl = tranche_pl(L, self.cs, 0., K) + bp = 1 + cl * self.tranche_running * 1e-4 + pl + return Legs(cl, pl, bp) def index_pv(self, epsilon=0., discounted=True): DP = self._default_prob(epsilon) @@ -178,7 +180,7 @@ class DualCorrTranche(): i = 0 for rho, k in zip(self.rho, self.K): - cl[i], pl[i] = self.tranche_legs(k, rho, epsilon) + cl[i], pl[i], _ = self.tranche_legs(k, rho, epsilon) i += 1 dK = np.diff(self.K) pl = np.diff(pl) / dK @@ -287,10 +289,10 @@ class DualCorrTranche(): def _greek_calc(self): eps = 1e-4 - indexbp = [self.index_pv().bond_price] + indexbp = [self.tranche_legs(1., 0.).bond_price] bp = [self.pv] for tweak in [eps, -eps, 2*eps]: - indexbp.append(self.index_pv(tweak).bond_price) + indexbp.append(self.tranche_legs(1., 0., tweak).bond_price) bp.append(self._pv(tweak)) return {'indexbp': indexbp, 'bp': bp} @@ -393,8 +395,9 @@ class TrancheBasket(BasketIndex): return pd.DataFrame(1 - sm, index=tickers, columns=self.cs.index) def tranche_legs(self, K, rho, complement=False, shortened=0): + Legs = namedtuple('TrancheLegs', 'coupon_leg, protection_leg') if ((K == 0. and not complement) or (K == 1. and complement)): - return 0., 0. + return Legs(0., 0.) elif ((K == 1. and not complement) or (K == 0. and complement)): return Legs(*self.index_pv()[:-1]) elif rho == -1.: @@ -411,7 +414,6 @@ class TrancheBasket(BasketIndex): self.recovery_rates, rho, self._Z, self._w, self._Ngrid) - Legs = namedtuple('TrancheLegs', 'coupon_leg, protection_leg') if complement: return Legs(tranche_cl(L, R, cs, K, 1.), tranche_pl(L, cs, K, 1.)) else: |
