diff options
Diffstat (limited to 'python/analytics')
| -rw-r--r-- | python/analytics/index.py | 56 | ||||
| -rw-r--r-- | python/analytics/portfolio.py | 11 |
2 files changed, 36 insertions, 31 deletions
diff --git a/python/analytics/index.py b/python/analytics/index.py index ae570c10..0d692d19 100644 --- a/python/analytics/index.py +++ b/python/analytics/index.py @@ -42,21 +42,16 @@ def g(index, spread, exercise_date, forward_yc=None, pv=None): else: return (spread - index.fixed_rate) * a * 1e-4 -def _key_from_index(index): - _, index_type, _, series, tenor = index.name.split() - series = int(series[1:]) - tenor = tenor.lower() + 'r' - return index_type, series, tenor - class Index(object): """ minimal class to represent a credit index """ __slots__ = ['fixed_rate', 'notional', '_start_date', '_end_date', - 'recovery', '_factor', '_fee_leg', '_default_leg', + 'recovery', '_version', '_fee_leg', '_default_leg', '_trade_date', '_yc', '_sc', '_risky_annuity', '_spread', '_price', 'name', 'issue_date', '_quote_is_price', '_direction', 'currency', '_step_in_date', '_accrued', '_value_date', '_dl_pv', '_pv', '_clean_pv', - '_original_clean_pv', '_original_trade_date', '_observed'] + '_original_clean_pv', '_original_trade_date', + 'index_type', 'series', 'tenor', '_observed'] def __init__(self, start_date, end_date, recovery, fixed_rate, notional = 10e6, quote_is_price=False, issue_date=None): """ @@ -74,7 +69,7 @@ class Index(object): self._start_date = start_date self._end_date = end_date self.recovery = recovery - self._factor = () + self._version = () self._fee_leg = FeeLeg(self._start_date, end_date, True, 1., 1.) self._default_leg = ContingentLeg(self._start_date, end_date, True) @@ -86,11 +81,10 @@ class Index(object): self.issue_date = issue_date self._quote_is_price = quote_is_price self._direction = -1. - self.currency = None - self._step_in_date, self._value_date = None, None - self._accrued = None - self._dl_pv, self._pv, self._clean_pv = None, None, None - self._original_clean_pv, self._original_trade_date = None, None + for attr in ['currency', '_step_in_date', '_value_date', '_accrued', + '_dl_pv', '_pv', '_clean_pv', '_original_clean_pv', + '_original_trade_date', 'index_type', 'series', 'tenor']: + setattr(self, attr, None) self._observed = WeakSet() def __hash__(self): @@ -346,7 +340,6 @@ class Index(object): self._observed.add(obj) def mark(self): - index_type, series, tenor = _key_from_index(self) if self.trade_date == datetime.date.today(): with init_bbg_session(BBG_IP) as session: security = self.name + " Corp" @@ -356,28 +349,38 @@ class Index(object): else: run = _engine.execute("""SELECT * FROM index_quotes WHERE index=%s AND series=%s AND tenor=%s AND date=%s""", - (index_type, series, tenor, self.trade_date)) + (self.index_type, self.series, self.tenor, self.trade_date)) rec = run.fetchone() self.spread = rec.closespread + @property def factor(self): - for lastdate, factor in getattr(self, '_factor'): + for lastdate, factor, _ in getattr(self, '_version'): if lastdate >= self.trade_date: return factor else: return 1 + @property + def version(self): + for lastdate, _, version in getattr(self, '_factor'): + if lastdate >= self.trade_date: + return version + else: + return None + @classmethod def from_name(cls, index=None, series=None, tenor=None, trade_date=datetime.date.today(), notional=10_000_000, redcode=None, maturity=None): if all([index, series, tenor]): - sql_str = "SELECT indexfactor, lastdate, maturity, coupon, issue_date " \ + sql_str = "SELECT indexfactor, lastdate, maturity, coupon, " \ + "issue_date, version " \ "FROM index_desc WHERE index=%s AND series=%s AND tenor = %s " \ "ORDER BY lastdate ASC" params = (index.upper(), series, tenor) elif all([redcode, maturity]): sql_str = "SELECT index, series, indexfactor, lastdate, maturity, " \ - "coupon, issue_date, tenor " \ + "coupon, issue_date, tenor, version " \ "FROM index_desc WHERE redindexcode=%s AND maturity=%s" params = (redcode, maturity) else: @@ -392,7 +395,7 @@ class Index(object): if tenor is None: tenor = df.tenor[0] index_type = index.upper() if index else df.loc[0,'index'] - series = series if series else df.series[0] + series = series if series else df.series.iat[0] df.loc[df.lastdate.isnull(), 'lastdate'] = maturity except exc.DataError as e: print(e) @@ -400,9 +403,13 @@ class Index(object): else: recovery = 0.4 if index_type == "IG" else 0.3 instance = cls(trade_date, maturity, recovery, coupon, notional, - index_type=="HY", df.issue_date[0]) - instance._factor = tuple((ld.date(), factor / 100) for ld, factor in \ - df[['lastdate', 'indexfactor']].itertuples(index=False)) + index_type == "HY", df.issue_date[0]) + instance._version = tuple((ld.date(), factor / 100, version) for ld, factor, version in \ + df[['lastdate', 'indexfactor', 'version']].itertuples(index=False)) + instance.index_type = index_type + instance.series = series + instance.tenor = tenor + instance.direction = "Buyer" tenor = tenor.upper() if tenor.endswith("R"): @@ -429,6 +436,9 @@ class Index(object): recovery = 0.4 if "IG" in rec.security_desc else 0.3 instance = cls(rec.trade_date, rec.maturity, recovery, rec.fixed_rate * 100, rec.notional, recovery==0.3, rec.issue_date) + r = _engine.execute("SELECT lastdate, indexfactor/100 AS factor, version FROM index_version " \ + "WHERE index=%s and series=%s", (rec.index, rec.series)) + instance._version = tuple(tuple(t) for t in r) instance.name = rec.security_desc instance.currency = rec.currency diff --git a/python/analytics/portfolio.py b/python/analytics/portfolio.py index c337a978..54d4cdeb 100644 --- a/python/analytics/portfolio.py +++ b/python/analytics/portfolio.py @@ -1,4 +1,4 @@ -from .index import Index, _key_from_index +from .index import Index from .option import BlackSwaption, VolatilitySurface from db import dbengine from warnings import warn @@ -33,13 +33,8 @@ class Portfolio: self.trades = trades self.indices = [t for t in trades if isinstance(t, Index)] self.swaptions = [t for t in trades if isinstance(t, BlackSwaption)] - self._keys = [] - trade_dates = set() - for index in self.indices: - self._keys.append(_key_from_index(index)) - #pick the first available trade_date - trade_dates.add(index.trade_date) - + trade_dates = set(index.trade_date for index in self.indices) + self._keys = [(index.index_type, index.series, index.tenor) for index in self.indices] for swaption in self.swaptions: trade_dates.add(swaption.index.trade_date) self._trade_date = trade_dates.pop() |
