aboutsummaryrefslogtreecommitdiffstats
path: root/python/risk/portfolio.py
blob: 9d87a6a638ad5c76988fb1283d44686b79bd55c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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 dawn_pool, dbconn
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, 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)
        portf += swaption_portf
        syn_portf = deepcopy(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"
        )
        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"),
        )

        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, dbengine("crt"), 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