diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/analytics/basket_index.py | 2 | ||||
| -rw-r--r-- | python/analytics/tranche_basket.py | 29 |
2 files changed, 14 insertions, 17 deletions
diff --git a/python/analytics/basket_index.py b/python/analytics/basket_index.py index 5b57b207..7efdbd56 100644 --- a/python/analytics/basket_index.py +++ b/python/analytics/basket_index.py @@ -67,7 +67,7 @@ class BasketIndex(CreditIndex): self.tweaks = [] self.start_date = previous_twentieth(value_date) self._ignore_hash = set(['_Z', '_w', '_skew', 'tenors', - 'index_desc', 'tweaks', '_ignore_hash']) + 'index_desc', 'tweaks', '_Legs', '_ignore_hash']) super().__init__(self.issue_date, maturities, curves, value_date=value_date) def __reduce__(self): diff --git a/python/analytics/tranche_basket.py b/python/analytics/tranche_basket.py index f710eb11..bf80a8e8 100644 --- a/python/analytics/tranche_basket.py +++ b/python/analytics/tranche_basket.py @@ -19,6 +19,7 @@ import numpy as np class DualCorrTranche(): _cache = LRU(64) + _Legs = namedtuple('Legs', 'coupon_leg, protection_leg, bond_price') def __init__(self, index_type: str, series: int, tenor: str, *, attach: float, detach: float, corr_attach: float, @@ -54,7 +55,7 @@ class DualCorrTranche(): 1., self._index.yc, self._index.maturities[0]) self._accrued = cds_accrued(value_date, tranche_running * 1e-4) self.use_trunc = use_trunc - self._ignore_hash = set(['_Z', '_w', 'cs', '_cache', '_ignore_hash']) + self._ignore_hash = set(['_Z', '_w', 'cs', '_cache', '_Legs', '_ignore_hash']) def _default_prob(self, epsilon=0.): return 1 - self._index.survival_matrix( @@ -106,11 +107,10 @@ 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 Legs(0., 0., 1.) + return self._Legs(0., 0., 1.) elif K == 1.: - return Legs(*self.index_pv(epsilon)) + return self._Legs(*self.index_pv(epsilon)) elif rho == -1.: raise ValueError("ρ needs to be a real number between 0. and 1.") else: @@ -131,7 +131,7 @@ class DualCorrTranche(): 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) + return self._Legs(cl, pl, bp) def index_pv(self, epsilon=0., discounted=True): DP = self._default_prob(epsilon) @@ -147,8 +147,7 @@ class DualCorrTranche(): pl = - np.diff(np.hstack((0., ELvec))) @ df cl = coupons @ (sizeadj * df) bp = 1 + cl * self._index.coupon(self.maturity) + pl - Pvs = namedtuple('IndexPvs', 'coupon_leg, protection_leg, bond_price') - return Pvs(cl, pl, bp) + return self._Legs(cl, pl, bp) @property def direction(self): @@ -297,6 +296,7 @@ class DualCorrTranche(): return {'indexbp': indexbp, 'bp': bp} class TrancheBasket(BasketIndex): + _Legs = namedtuple('Legs', 'coupon_leg, protection_leg, bond_price') def __init__(self, index_type: str, series: int, tenor: str, *, value_date: pd.Timestamp=pd.Timestamp.today().normalize()): super().__init__(index_type, series, [tenor], value_date=value_date) @@ -395,11 +395,10 @@ 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 Legs(0., 0.) + return 0., 0. elif ((K == 1. and not complement) or (K == 0. and complement)): - return Legs(*self.index_pv()[:-1]) + self.index_pv()[:-1] elif rho == -1.: raise ValueError("rho needs to be a real number between 0. and 1.") else: @@ -415,9 +414,9 @@ class TrancheBasket(BasketIndex): rho, self._Z, self._w, self._Ngrid) if complement: - return Legs(tranche_cl(L, R, cs, K, 1.), tranche_pl(L, cs, K, 1.)) + return tranche_cl(L, R, cs, K, 1.), tranche_pl(L, cs, K, 1.) else: - return Legs(tranche_cl(L, R, cs, 0., K), tranche_pl(L, cs, 0., K)) + return tranche_cl(L, R, self.cs, 0., K), tranche_pl(L, self.cs, 0., K) def tranche_pvs(self, protection=False, complement=False, shortened=0): """ computes coupon leg, protection leg and bond price. @@ -440,8 +439,7 @@ class TrancheBasket(BasketIndex): bp = -pl - cl + self._accrued else: bp = 1 + pl + cl - self._accrued - Pvs = namedtuple('TranchePvs', 'coupon_leg, protection_leg, bond_price') - return Pvs(cl, pl, bp) + return self._Legs(cl, pl, bp) def index_pv(self, discounted=True, shortened=0): if shortened > 0: @@ -462,8 +460,7 @@ class TrancheBasket(BasketIndex): pl = - np.diff(np.hstack((0., ELvec))) @ df cl = coupons @ (sizeadj * df) bp = 1 + cl * self.coupon(self.maturity) + pl - Pvs = namedtuple('IndexPvs', 'coupon_leg, protection_leg, bond_price') - return Pvs(cl, pl, bp) + return self._Legs(cl, pl, bp) def expected_loss(self, discounted=True, shortened=0): if shortened > 0: |
