diff options
Diffstat (limited to 'python/analytics')
| -rw-r--r-- | python/analytics/portfolio.py | 2 | ||||
| -rw-r--r-- | python/analytics/tranche_basket.py | 40 |
2 files changed, 39 insertions, 3 deletions
diff --git a/python/analytics/portfolio.py b/python/analytics/portfolio.py index 2f98053f..a4ed393d 100644 --- a/python/analytics/portfolio.py +++ b/python/analytics/portfolio.py @@ -188,7 +188,7 @@ class Portfolio: name = f"{t.index_type}{t.series} {t.tenor}" r = ("Tranche", name, t.notional, None, None, t.direction, None, None, None, t.upfront, - None, None, None, None, + t.delta, t.gamma, None, None, t.attach, t.detach, t.rho[0], t.rho[1]) else: raise TypeError diff --git a/python/analytics/tranche_basket.py b/python/analytics/tranche_basket.py index 853f8468..34068ae1 100644 --- a/python/analytics/tranche_basket.py +++ b/python/analytics/tranche_basket.py @@ -187,10 +187,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, "Detach Corr", self.rho[1] * 100]] + ["Attach Corr", self.rho[0] * 100, "Detach Corr", self.rho[1] * 100], + ["Delta", self.delta, "Gamma", self.gamma]] format_strings = [[None, '{:,.0f}', None, '{:,.4f}%'], [None, '{:.2f}', None, '{:,.2f}'], - [None, '{:.3f}%', None, '{:.3f}%']] + [None, '{:.3f}%', None, '{:.3f}%'], + [None, '{:.3f}', None, '{:.3f}']] s += build_table(rows, format_strings, "{:<20}{:>19}\t\t{:<19}{:>16}") return "\n".join(s) @@ -229,6 +231,40 @@ class DualCorrTranche(): else: self.rho = np.array([corr for corr, in c]) + @property + def tranche_factor(self): + return (self.K[1] - self.K[0]) / (self.K_orig[1] + - self.K_orig[0]) * self._index.factor + + @property + def delta(self): + calc = self._greek_calc() + factor = self.tranche_factor / self._index.factor + return (calc['bp'][1] - calc['bp'][2]) / (calc['indexbp'][1] + - calc['indexbp'][2]) * factor + + @property + def gamma(self): + calc = self._greek_calc() + factor = self.tranche_factor / self._index.factor + deltaplus = (calc['bp'][3] - calc['bp'][0]) / (calc['indexbp'][3] + - calc['indexbp'][0]) * factor + delta = (calc['bp'][1] - calc['bp'][2]) / (calc['indexbp'][1] + - calc['indexbp'][2]) * factor + return (deltaplus - delta) / (calc['indexbp'][1] - calc['indexbp'][0]) / 100 + + def _greek_calc(self): + eps = 1e-4 + self._Ngrid = 301 + indexbp = [self._index.pv()[0]] + bp = [self.pv] + orig_curves = self._index.curves + for tweak in [eps, -eps, 2*eps]: + self._index.tweak_portfolio(tweak, self.maturity, False) + indexbp.append(self._index.pv()[0]) + bp.append(self.pv) + self._index.curves = orig_curves + return {'indexbp': indexbp, 'bp': bp} class TrancheBasket(BasketIndex): def __init__(self, index_type: str, series: int, tenor: str, *, |
