diff options
Diffstat (limited to 'python/analytics/tranche_basket.py')
| -rw-r--r-- | python/analytics/tranche_basket.py | 41 |
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 |
