diff options
Diffstat (limited to 'python/analytics/index.py')
| -rw-r--r-- | python/analytics/index.py | 144 |
1 files changed, 73 insertions, 71 deletions
diff --git a/python/analytics/index.py b/python/analytics/index.py index 8bdddf03..0f53425e 100644 --- a/python/analytics/index.py +++ b/python/analytics/index.py @@ -67,6 +67,7 @@ class CreditIndex(CreditDefaultSwap): "series", "tenor", "_quote_is_price", + "_floating_version", ) def __init__( @@ -79,96 +80,95 @@ class CreditIndex(CreditDefaultSwap): redcode=None, maturity=None, ): + self._floating_version = True if all([redcode, maturity]): r = serenitas_engine.execute( - "SELECT index, series, tenor FROM index_desc " - "WHERE redindexcode=%s AND maturity = %s", + "SELECT index, series, tenor, coupon, issue_date, factor, version, cumloss " + "FROM index_desc " + "WHERE redindexcode=%s AND maturity=%s", (redcode, maturity), ) - index_type, series, tenor = next(r) - - if all([index_type, series, tenor]): + index_type, series, tenor, coupon, issue_date, factor, version, cumloss = next(r) + self._floating_version = False + elif all([index_type, series, tenor]): sql_str = ( "SELECT indexfactor, lastdate, maturity, coupon, " "issue_date, version, cumulativeloss " - "FROM index_desc WHERE index=%s AND series=%s AND tenor = %s " + "FROM index_desc WHERE index=%s AND series=%s AND tenor=%s " "ORDER BY lastdate ASC" ) params = (index_type.upper(), series, tenor) + try: + df = pd.read_sql_query( + sql_str, + serenitas_engine, + parse_dates=["lastdate", "issue_date"], + params=params, + ) + maturity = df.maturity[0] + coupon = df.coupon[0] + issue_date = df.issue_date[0] + df.loc[df.lastdate.isnull(), "lastdate"] = maturity + except DataError as e: + print(e) + return None else: raise ValueError("Not enough information to load the index.") - try: - df = pd.read_sql_query( - sql_str, - serenitas_engine, - parse_dates=["lastdate", "issue_date"], - params=params, - ) - maturity = df.maturity[0] - coupon = df.coupon[0] - if tenor is None: - tenor = df.tenor[0] - index_type = index_type.upper() if index_type else df.loc[0, "index"] - series = series if series else df.series.iat[0] - df.loc[df.lastdate.isnull(), "lastdate"] = maturity - except DataError as e: - print(e) - return None - else: - recovery = 0.3 if index_type == "HY" else 0.4 - super().__init__( - previous_twentieth(value_date), - maturity, - recovery, - coupon, - notional, - df.issue_date[0], - ) - self._quote_is_price = index_type == "HY" + + recovery = 0.3 if index_type == "HY" else 0.4 + super().__init__( + previous_twentieth(value_date), + maturity, + recovery, + coupon, + notional, + issue_date, + ) + self._quote_is_price = index_type == "HY" + if self._floating_version: self._indic = tuple( (ld, factor / 100, cumloss, version) for ld, factor, cumloss, version in ( - df[ - ["lastdate", "indexfactor", "cumulativeloss", "version"] - ].itertuples(index=False) + df[ + ["lastdate", "indexfactor", "cumulativeloss", "version"] + ].itertuples(index=False) ) ) - self.index_type = index_type - self.series = series - self.tenor = tenor + self.index_type = index_type + self.series = series + self.tenor = tenor - tenor = tenor.upper() - if tenor.endswith("R"): - tenor = tenor[:-1] - if index_type in ("IG", "HY"): - self.name = "CDX {} CDSI S{} {}".format(index_type, series, tenor) - elif index_type == "EU": - self.name = f"ITRX EUR CDSI S{series} {tenor}" - elif index_type == "XO": - self.name = f"ITRX XOVER CDSI S{series} {tenor}" + tenor = tenor.upper() + if tenor.endswith("R"): + tenor = tenor[:-1] + if index_type in ("IG", "HY"): + self.name = "CDX {} CDSI S{} {}".format(index_type, series, tenor) + elif index_type == "EU": + self.name = f"ITRX EUR CDSI S{series} {tenor}" + elif index_type == "XO": + self.name = f"ITRX XOVER CDSI S{series} {tenor}" + + if index_type in ("IG", "HY"): + self.currency = "USD" + else: + self.currency = "EUR" + self.value_date = value_date - if index_type in ("IG", "HY"): - self.currency = "USD" - else: - self.currency = "EUR" - self.value_date = value_date @classmethod def from_tradeid(cls, trade_id): r = dawn_engine.execute( """ - SELECT index, series, tenor, trade_date, notional, security_desc, - protection, upfront + SELECT trade_date, notional, security_desc, + protection, upfront, maturity FROM cds - LEFT JOIN index_desc - ON security_id = redindexcode AND cds.maturity = index_desc.maturity WHERE id=%s""", (trade_id,), ) rec = r.fetchone() if rec is None: raise ValueError(f"No index trade for id: {trade_id}") - instance = cls(rec.index, rec.series, rec.tenor, rec.trade_date, rec.notional) + instance = cls(redcode=rec.redcode, maturity=rec.maturity, value_date=rec.trade_date, notional=rec.notional) instance.name = rec.security_desc instance.direction = rec.protection @@ -214,9 +214,10 @@ class CreditIndex(CreditDefaultSwap): self.ref = ref_data[security][field] else: run = serenitas_engine.execute( - """SELECT * FROM index_quotes - WHERE index=%s AND series=%s AND tenor=%s AND date=%s""", - (self.index_type, self.series, self.tenor, self.value_date), + "SELECT * FROM index_quotes " + "WHERE " + "index=%s AND series=%s AND tenor=%s AND date=%s AND version=%s", + (self.index_type, self.series, self.tenor, self.value_date, self.version), ) rec = run.fetchone() self.spread = rec.closespread @@ -226,15 +227,16 @@ class CreditIndex(CreditDefaultSwap): @value_date.setter def value_date(self, d): CreditDefaultSwap.value_date.__set__(self, d) - for lastdate, factor, cumloss, version in self._indic: - if lastdate >= self.value_date: - self._factor = factor - self._version = version - self._cumloss = cumloss - break - else: - self._factor = 1.0 - self._version = 1 + if self._floating_version: + for lastdate, factor, cumloss, version in self._indic: + if lastdate >= self.value_date: + self._factor = factor + self._version = version + self._cumloss = cumloss + break + else: + self._factor = 1.0 + self._version = 1 @property def factor(self): |
