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