import serenitas.analytics import numpy as np from serenitas.analytics.base import Trade from serenitas.analytics.index_data import on_the_run from serenitas.analytics.api import CreditIndex, BlackSwaptionVolSurface from copy import deepcopy from .tranches import get_tranche_portfolio from .swaptions import get_swaption_portfolio from .bonds import subprime_risk, clo_risk, crt_risk from .indices import get_index_portfolio from serenitas.utils.db import dbengine from serenitas.utils.db2 import dbconn from serenitas.utils.pool import dawn_pool from pandas.tseries.offsets import BDay def hy_equiv_trade(value_date, notional): return CreditIndex( "HY", on_the_run("HY", value_date), "5yr", value_date=value_date, notional=notional, ) def build_portfolio(position_date, value_date=None, fund="SERCGMAST"): """ Output two portfolios: 1) All synthetic + curve with just delta-proxy + dummy index as cash bonds proxy (portf) 2) All synthetic (portf_syn) """ serenitas.analytics._local = False if value_date is None: value_date = position_date Trade.init_ontr(value_date) with dawn_pool.connection() as conn: portf = get_tranche_portfolio(position_date, conn, False, [fund]) swaption_portf = get_swaption_portfolio(position_date, conn, fund=fund) swaption_portf.trade_ids = [tid[:-1] for tid in swaption_portf.trade_ids] portf += swaption_portf curve_portf = get_index_portfolio( position_date, conn, fund, include_strategies="%CURVE" ) nocurve_portf = get_index_portfolio( position_date, conn, fund, exclude_strategies="%CURVE" ) basis_portf = get_index_portfolio( position_date, conn, fund, include_strategies="%BASIS" ) portf.add_trade( hy_equiv_trade(value_date, -basis_portf.hy_equiv), ("CASH_BASIS", "negate_basis_trades"), ) syn_portf = deepcopy(portf) portf += nocurve_portf curve_portf.value_date = value_date curve_portf.mark() portf.add_trade( hy_equiv_trade(value_date, curve_portf.hy_equiv), ("curve_trades", "curve_trades"), ) if not curve_portf: syn_portf = nocurve_portf else: syn_portf += curve_portf + nocurve_portf # get bond risks: rmbs_pos = subprime_risk(position_date, conn, dbengine("rmbs_model"), fund=fund) crt_pos = crt_risk(position_date, conn, fund=fund) portf.add_trade( hy_equiv_trade(value_date, -rmbs_pos.get("hy_equiv", np.zeros(1)).sum()), ("rmbs_bonds", "rmbs_bonds"), ) portf.add_trade( hy_equiv_trade(value_date, -crt_pos.get("hy_equiv", np.zeros(1)).sum()), ("crt_bonds", "crt_bonds"), ) with dbconn("etdb") as etconn: clo_pos = clo_risk(position_date, conn, etconn, fund=fund) if clo_pos is not None: portf.add_trade( hy_equiv_trade(value_date, -clo_pos["hy_equiv"].sum()), ("clo_bonds", "clo_bonds"), ) for p in [portf, syn_portf]: p.value_date = value_date p.mark(interp_method="bivariate_linear") p.reset_pv() return portf, syn_portf def generate_vol_surface(portf, try_days_back=5, source="MS"): vol_surface = {} for trade in portf.swaptions: try: vs = BlackSwaptionVolSurface( trade.index.index_type, trade.index.series, value_date=portf.value_date, interp_method="bivariate_linear", ) except: vs = BlackSwaptionVolSurface( trade.index.index_type, trade.index.series, value_date=portf.value_date - BDay(try_days_back), interp_method="bivariate_linear", ) vol_surface[ (trade.index.index_type, trade.index.series, trade.option_type) ] = vs[vs.list(source=source, option_type=trade.option_type)[-1]] return vol_surface