aboutsummaryrefslogtreecommitdiffstats
path: root/python/risk/portfolio.py
blob: 8598f3ae897736b70d9a70c0b5efa3a8d007b3ff (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
import serenitas.analytics
import numpy as np

from serenitas.analytics import on_the_run, 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 dbconn, dbengine
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

    serenitas.analytics.init_ontr(value_date)
    conn = dbconn("dawndb")
    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