aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/analytics/tranche_basket.py21
-rw-r--r--python/analytics/utils.py18
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),)):