aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/analytics/tranche_basket.py26
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: