aboutsummaryrefslogtreecommitdiffstats
path: root/python/risk/portfolio.py
blob: 88e10f26bece4a23fc74d2f07e344456e1115f51 (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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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