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