diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/analytics/basket_index.py | 80 |
1 files changed, 38 insertions, 42 deletions
diff --git a/python/analytics/basket_index.py b/python/analytics/basket_index.py index 23ed3be1..8dbc0f9c 100644 --- a/python/analytics/basket_index.py +++ b/python/analytics/basket_index.py @@ -1,6 +1,6 @@ from .index_data import get_index_quotes, get_singlenames_curves_prebuilt -from . import serenitas_engine -from .utils import tenor_t, get_fx +from . import serenitas_pool +from .utils import get_fx from functools import partial from pyisda.cdsone import upfront_charge, spread_from_upfront from pyisda.credit_index import CreditIndex @@ -47,21 +47,21 @@ class BasketIndex(CreditIndex): self.recovery = 0.3 else: self.recovery = 0.4 - self.index_desc = pd.read_sql_query( - "SELECT tenor, maturity, coupon * 1e-4 AS coupon, " - "issue_date " - "FROM index_maturity " - "WHERE index=%s AND series=%s", - serenitas_engine, - index_col="tenor", - params=(index_type, series), - parse_dates=["maturity", "issue_date"], - ) - if self.index_desc.empty: + conn = serenitas_pool.getconn() + with conn.cursor() as c: + c.execute( + "SELECT tenor, maturity, (coupon * 1e-4)::float AS coupon, " + "issue_date " + "FROM index_maturity " + "WHERE index=%s AND series=%s AND tenor IN %s " + "ORDER BY maturity", + (index_type, series, tuple(tenors)) + ) + self.index_desc = list(c) + if not self.index_desc: raise ValueError(f"Index {index_type} {series} doesn't exist") - self._index_version = tuple( - tuple(r.values()) - for r in serenitas_engine.execute( + with conn.cursor() as c: + c.execute( "SELECT lastdate," " indexfactor/100 AS factor," " cumulativeloss/100 AS cum_loss," @@ -71,14 +71,13 @@ class BasketIndex(CreditIndex): "ORDER BY lastdate", (index_type, series), ) - ) + self._index_version = list(c) + serenitas_pool.putconn(conn) self._update_factor(value_date) - self.issue_date = self.index_desc.issue_date[0] - self.index_desc = self.index_desc.loc[tenors].sort_values("maturity") - self.tenors = {t: m.date() for t, m in self.index_desc.maturity.items()} - maturities = self.index_desc.maturity.dt.to_pydatetime() - self.index_desc = self.index_desc.reset_index().set_index("maturity") - self.index_desc.tenor = self.index_desc.tenor.astype(tenor_t) + self.issue_date = self.index_desc[0].issue_date + self.tenors = {t: m for t, m, _, _ in self.index_desc} + self.coupons = [r.coupon for r in self.index_desc] + maturities = [r.maturity for r in self.index_desc] curves = get_singlenames_curves_prebuilt(index_type, series, value_date) self.currency = "EUR" if index_type in ["XO", "EU"] else "USD" @@ -198,24 +197,22 @@ class BasketIndex(CreditIndex): else: r = super().dispersion(self.yc, use_log=use_log) return pd.Series( - r, index=self.index_desc.tenor, name="gini" if use_gini else "dispersion" + r, index=self.tenors.keys(), name="gini" if use_gini else "dispersion" ) def accrued(self, maturity=None): if maturity is None: r = [] - for m in self.maturities: - coupon = self.index_desc.coupon[m] - r.append(super().accrued(coupon)) - return pd.Series(r, index=self.index_desc.tenor, name="accrued") + for c in self.coupons: + r.append(super().accrued(c)) + return pd.Series(r, index=self.tenors.keys(), name="accrued") else: - return super().accrued(self.index_desc.coupon[maturity]) + return super().accrued(self.coupon(maturity)) def pv(self, maturity=None, epsilon=0.0, coupon=None): if maturity is None: r = [] - for m in self.maturities: - coupon = self.index_desc.coupon[m] + for _, m, coupon, _ in self.index_desc: r.append( super().pv( self.step_in_date, @@ -226,7 +223,7 @@ class BasketIndex(CreditIndex): epsilon, ) ) - return pd.Series(r, index=self.index_desc.tenor, name="pv") + return pd.Series(r, index=self.tenors.keys(), name="pv") else: return super().pv( self.step_in_date, @@ -243,7 +240,7 @@ class BasketIndex(CreditIndex): ) def coupon_leg(self, maturity=None): - return self.index_desc.coupon.values * self.duration() + return np.array(self.coupons) * self.duration() def spread(self, maturity=None): return self.protection_leg(maturity) / self.duration(maturity) * 1e4 @@ -257,7 +254,7 @@ class BasketIndex(CreditIndex): self.step_in_date, self.cash_settle_date, m, self.yc ) ) - return pd.Series(r, index=self.index_desc.tenor, name="protection_leg") + return pd.Series(r, index=self.tenors.keys(), name="protection_leg") else: return super().protection_leg( self.step_in_date, self.cash_settle_date, maturity, self.yc @@ -272,7 +269,7 @@ class BasketIndex(CreditIndex): self.step_in_date, self.cash_settle_date, m, self.yc ) ) - return pd.Series(r, index=self.index_desc.tenor, name="duration") + return pd.Series(r, index=self.tenors.keys(), name="duration") else: return super().duration( self.step_in_date, self.cash_settle_date, maturity, self.yc @@ -293,8 +290,7 @@ class BasketIndex(CreditIndex): index_quotes = {} if maturity is None: r = [] - for m in self.maturities: - coupon = self.index_desc.coupon[m] + for _, m, coupon, _ in self.index_desc: index_quote = index_quotes.get(m, np.nan) r.append( super().theta( @@ -307,7 +303,7 @@ class BasketIndex(CreditIndex): theta_date, ) ) - return pd.Series(r, index=self.index_desc.tenor, name="theta") + return pd.Series(r, index=self.tenors.keys(), name="theta") else: return super().theta( self.step_in_date, @@ -321,13 +317,13 @@ class BasketIndex(CreditIndex): def coupon(self, maturity=None, assume_flat=True): if maturity is None: - return self.index_desc.set_index("tenor").coupon + return pd.Series(self.coupons, index=self.tenors.keys(), name="coupon") else: try: - return self.index_desc.coupon[maturity] - except KeyError: + return self.coupons[self.maturities.index(maturity)] + except ValueError: if assume_flat: - return self.index_desc.coupon.iat[0] + return self.coupons[0] else: raise ValueError("Non standard maturity: coupon must be provided") |
