diff options
Diffstat (limited to 'python/analytics/portfolio.py')
| -rw-r--r-- | python/analytics/portfolio.py | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/python/analytics/portfolio.py b/python/analytics/portfolio.py index e2f35a68..66cdfe0c 100644 --- a/python/analytics/portfolio.py +++ b/python/analytics/portfolio.py @@ -1,15 +1,32 @@ -from .index import Index +from .index import Index, _key_from_index from .option import BlackSwaption, VolatilitySurface from db import dbengine from warnings import warn +import pandas as pd +import numpy as np serenitasdb = dbengine('serenitasdb') -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 +def portf_repr(method): + def f(*args): + obj = args[0] + thousands = lambda x: "{:,.2f}".format(x) + percent = lambda x: "N/A" if np.isnan(x) else f"{100*x:.2f}%" + header = "Portfolio {}\n\n".format(obj.trade_date) + kwargs = {'formatters': {'Notional': thousands, + 'PV': thousands, + 'Delta': percent, + 'Gamma': percent, + 'Theta': thousands, + 'Vega': thousands, + 'Vol': percent, + 'Ref': thousands}, + 'index': False} + if method == 'string': + kwargs['line_width'] = 100 + s = getattr(obj._todf(), 'to_' + method)(**kwargs) + return header + s + return f class Portfolio: def __init__(self, trades): @@ -123,3 +140,26 @@ class Portfolio: @property def dv01(self): return sum(t.dv01 for t in self.trades) + + def _todf(self): + headers = ["Product", "Index", "Notional", "Ref", "Direction", "Expiry", + "Vol", "PV", "Delta", "Gamma", "Theta", "Vega"] + rec = [] + for t in self.trades: + if isinstance(t, Index): + index_type, series, tenor = _key_from_index(t) + r = ("Index", f"{index_type}{series} {tenor}", + t.notional, t.ref, t.direction, "N/A", None, t.pv, 1., 0., t.theta, 0.) + elif isinstance(t, BlackSwaption): + index_type, series, tenor = _key_from_index(t.index) + r = ("Swaption", f"{index_type}{series} {tenor}", + t.notional, t.ref, t.direction, t.forward_date, t.sigma, t.pv, + t.delta, t.gamma, t.theta, t.vega) + else: + raise TypeError + rec.append(r) + return pd.DataFrame.from_records(rec, columns=headers) + + __repr__ = portf_repr('string') + + _repr_html_ = portf_repr('html') |
