aboutsummaryrefslogtreecommitdiffstats
path: root/python/analytics/tranche_basket.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/analytics/tranche_basket.py')
-rw-r--r--python/analytics/tranche_basket.py41
1 files changed, 28 insertions, 13 deletions
diff --git a/python/analytics/tranche_basket.py b/python/analytics/tranche_basket.py
index cea03c73..e47343fb 100644
--- a/python/analytics/tranche_basket.py
+++ b/python/analytics/tranche_basket.py
@@ -11,7 +11,7 @@ from pyisda.date import cds_accrued
from scipy.optimize import brentq
from scipy.interpolate import CubicSpline, PchipInterpolator
from scipy.special import logit, expit
-import concurrent.futures
+import datetime
import pandas as pd
import numpy as np
@@ -19,26 +19,39 @@ class TrancheBasket(BasketIndex):
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)
- self.tranche_quotes = get_tranche_quotes(index_type, series, tenor, value_date.date())
+ self.tenor = tenor
index_desc = self.index_desc.reset_index('maturity').set_index('tenor')
self.maturity = index_desc.loc[tenor].maturity
- self.start_date, self.cs = credit_schedule(value_date, tenor[:-1], 1, self.yc, self.maturity)
+ self._get_tranche_quotes(value_date)
self.K_orig = np.hstack((0., self.tranche_quotes.detach)) / 100
self.K = adjust_attachments(self.K_orig, self.cumloss, self.factor)
- if index_type == "HY":
+ self._Ngh = 250
+ self._Ngrid = 201
+ self._Z, self._w = GHquad(self._Ngh)
+ self.rho = np.full(self.K.size, np.nan)
+
+ def _get_tranche_quotes(self, value_date):
+ self.start_date, self.cs = credit_schedule(value_date, self.tenor[:-1],
+ 1, self.yc, self.maturity)
+ if isinstance(value_date, datetime.datetime):
+ value_date = value_date.date()
+ self.tranche_quotes = get_tranche_quotes(self.index_type, self.series,
+ self.tenor, value_date)
+ if self.tranche_quotes.empty:
+ raise ValueError(f"no tranche quotes for day {value_date}")
+ if self.index_type == "HY":
self.tranche_quotes['quotes'] = 1 - self.tranche_quotes.trancheupfrontmid / 100
else:
self.tranche_quotes['quotes'] = self.tranche_quotes.trancheupfrontmid / 100
self.tranche_quotes['running'] = self.tranche_quotes.trancherunningmid * 1e-4
-
- if index_type == "XO":
+ if self.index_type == "XO":
coupon = 500 * 1e-4
self.tranche_quotes.quotes.iat[3] = self._snacpv(
self.tranche_quotes.running.iat[3], coupon, 0.4)
self.tranche_quotes.running = coupon
- if index_type == "EU":
- if series >= 21:
+ if self.index_type == "EU":
+ if self.series >= 21:
coupon = 100 * 1e-4
for i in [2, 3]:
self.tranche_quotes.quotes.iat[i] = self._snacpv(
@@ -46,7 +59,7 @@ class TrancheBasket(BasketIndex):
coupon,
0. if i == 2 else 0.4)
self.tranche_quotes.running.iat[i] = coupon
- elif series == 9:
+ elif self.series == 9:
for i in [3, 4, 5]:
coupon = 25 * 1e-4 if i == 5 else 100 * 1e-4
recov = 0.4 if i == 5 else 0
@@ -59,10 +72,12 @@ class TrancheBasket(BasketIndex):
for r in self.tranche_quotes.running])
self.tranche_quotes.quotes -= self._accrued
- self._Ngh = 250
- self._Ngrid = 201
- self._Z, self._w = GHquad(self._Ngh)
- self.rho = np.full(self.K.size, np.nan)
+ value_date = property(BasketIndex.value_date.__get__)
+
+ @value_date.setter
+ def value_date(self, d: pd.Timestamp):
+ BasketIndex.value_date.__set__(self, d)
+ self._get_tranche_quotes(d)
def tranche_factors(self):
return np.diff(self.K) / np.diff(self.K_orig) * self.factor