aboutsummaryrefslogtreecommitdiffstats
path: root/python/globeop_ce_tranche.py
blob: b54608ec9e46e9d6cf38f9963481e4e3b3e41ae2 (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
import datetime

from serenitas.utils.db import dbconn
from serenitas.ops.trade_dataclasses import CDSDeal
from serenitas.ops.funds import Service


def calculate_attach_detach(redcode, orig_attach, orig_detach, conn):
    with conn.cursor() as c:
        c.execute(
            "SELECT indexfactor, cumulativeloss FROM index_factors WHERE redindexcode=%s",
            (redcode,),
        )
        (factor, cumulativeloss) = c.fetchone()
        detach = factor * min(max((orig_detach - cumulativeloss) / factor, 0), 1)
        attach = factor * min(max((orig_attach - cumulativeloss) / factor, 0.0), 1.0)
    return attach, detach


def upload_new_trades(index, affected_series, fund, event_date, conn, event_name):
    NEW_TRADES_QUERY = (
        "SELECT trg.*, b.security_id, cds.currency, cds.fixed_rate, cds.cp_code as custodian_cpty, cds.cp_code, cds.protection, cds.account_code, cds.frequency, "
        "cds.dealid, cds.portfolio, cds.folder, cds.swap_type, cds.clearing_facility, a.custodian, a.cash_account "
        "FROM tranche_risk_globeop trg "
        "LEFT JOIN LATERAL (SELECT redindexcode as security_id FROM index_desc WHERE index_desc.lastdate >%s AND index_desc.index=trg.index AND index_desc.series=trg.series LIMIT 1) b ON TRUE "
        "LEFT JOIN cds ON trg.trade_id=cds.id "
        "LEFT JOIN accounts a ON cds.account_code=a.code "
        "WHERE date=%s AND trg.fund=%s AND index=%s AND series in %s"
    )

    with conn.cursor() as c:
        c.execute(
            NEW_TRADES_QUERY,
            (
                event_date,
                event_date,
                fund,
                index,
                affected_series,
            ),
        )
        service = Service[fund]
        for row in c:
            d = row._asdict()
            d["notional"] = abs(d["notional"])
            d["traded_level"] = None
            d["upfront"] = (d["serenitas_clean_nav"] + d["serenitas_accrued"]) * -1
            d["trade_date"] = event_date
            d["dealid"] = f'{d["dealid"]}_{event_name}'
            d["attach"], d["detach"] = calculate_attach_detach(
                d["security_id"], d["orig_attach"], d["orig_detach"], conn
            )
            trade = CDSDeal.from_dict(**d)
            service.push_trade(trade, "NEW")
        service.build_buffer(trade_type="cds")


if __name__ == "__main__":
    index = "HY"
    affected_series = (
        34,
        35,
        36,
        37,
        38,
        39,
    )
    fund = "BOWDST"
    event_date = datetime.date(2023, 4, 13)
    settlement_date = datetime.date(2023, 4, 18)
    event_name = "DIAMOND"

    conn = dbconn("dawndb")
    upload_new_trades(index, affected_series, fund, event_date, conn, event_name)
    # terminate_old_trades(index, affected_series, fund, event_date, )