diff options
Diffstat (limited to 'python/analytics')
| -rw-r--r-- | python/analytics/tranche_basket.py | 21 | ||||
| -rw-r--r-- | python/analytics/utils.py | 18 |
2 files changed, 25 insertions, 14 deletions
diff --git a/python/analytics/tranche_basket.py b/python/analytics/tranche_basket.py index 876781cb..06fa148b 100644 --- a/python/analytics/tranche_basket.py +++ b/python/analytics/tranche_basket.py @@ -57,6 +57,7 @@ class DualCorrTranche(): 1., self._index.yc, self._index.maturities[0]) self._accrued = cds_accrued(value_date, tranche_running * 1e-4) self.use_trunc = use_trunc + self._tranche_id = None self._ignore_hash = set(['_Z', '_w', 'cs', '_cache', '_Legs', '_ignore_hash']) def _default_prob(self, epsilon=0.): @@ -221,12 +222,12 @@ class DualCorrTranche(): "{:<20}\t{:>15}".format("Direction", self.direction)] rows = [["Notional", self.notional, "PV", self.pv *100], ["Attach", self.attach, "Detach", self.detach], - ["Attach Corr", self.rho[0] * 100 if self.rho[0] else "N/A", - "Detach Corr", self.rho[1] * 100 if self.rho[1] else "N/A"], + ["Attach Corr", self.rho[0], "Detach Corr", self.rho[1]], ["Delta", self.delta, "Gamma", self.gamma]] format_strings = [[None, '{:,.0f}', None, '{:,.4f}%'], [None, '{:.2f}', None, '{:,.2f}'], - [None, '{:.3f}%', None, '{:.3f}%'], + [None, lambda corr: f'{corr * 100:.3f}%' if corr else 'N/A', None, + lambda corr: f'{corr * 100:.3f}%' if corr else 'N/A'], [None, '{:.3f}', None, '{:.3f}']] s += build_table(rows, format_strings, "{:<20}{:>19}\t\t{:<19}{:>16}") return "\n".join(s) @@ -251,7 +252,7 @@ class DualCorrTranche(): names=['spread_shock', 'corr_shock'])) def mark(self, **args): - sql_string = ("SELECT corr_at_detach FROM tranche_risk b " + sql_string = ("SELECT tranche_id, corr_at_detach FROM tranche_risk b " "LEFT JOIN tranche_quotes a ON a.id = b.tranche_id " "WHERE a.index=%s AND a.series=%s AND a.tenor=%s " "AND quotedate::date=%s " @@ -262,11 +263,14 @@ class DualCorrTranche(): self.tenor, self.value_date, self.attach, self.attach)) if self.attach == 0: - self.rho[1], = next(c) + self._tranche_id, self.rho[1] = next(c) elif self.detach == 100: - self.rho[0], = next(c) + self._tranche_id, self.rho[0] = next(c) else: - self.rho = [corr for corr, in c] + self.rho = [] + for tranche_id, corr in c: + self.rho.append(corr) + self._tranche_id = tranche_id @property def tranche_factor(self): @@ -315,7 +319,7 @@ class TrancheBasket(BasketIndex): self.K_orig = np.hstack((0., self.tranche_quotes.detach)) / 100 self.K = adjust_attachments(self.K_orig, self.cumloss, self.factor) self._Ngh = 250 - self._Ngrid = 201 + self._Ngrid = 301 self._Z, self._w = GHquad(self._Ngh) self.rho = np.full(self.K.size, np.nan) self.cs = credit_schedule(value_date, self.tenor[:-1], @@ -563,7 +567,6 @@ class TrancheBasket(BasketIndex): def tranche_deltas(self, complement=False): eps = 1e-4 - self._Ngrid = 301 index_list = [self] for tweak in [eps, -eps, 2*eps]: tb = deepcopy(self) diff --git a/python/analytics/utils.py b/python/analytics/utils.py index fd7779e1..2656147a 100644 --- a/python/analytics/utils.py +++ b/python/analytics/utils.py @@ -95,11 +95,19 @@ def roll_date(d, tenor, nd_array=False): def build_table(rows, format_strings, row_format): - r = [] - for row, format_string in zip(rows, format_strings): - row = [f.format(r) if f else r for r, f in zip(row, format_string)] - r.append(row_format.format(*row)) - return r + + def apply_format(row, format_string): + for r, f in zip(row, format_string): + if f is None: + yield r + else: + if callable(f): + yield f(r) + elif isinstance(f, str): + yield f.format(r) + + return [row_format.format(*apply_format(row, format_string)) + for row, format_string in zip(rows, format_strings)] def memoize(f=None, *, hasher=lambda args: (hash(args),)): |
