aboutsummaryrefslogtreecommitdiffstats
path: root/python/cds_rebook.py
blob: 165aaccf654071d26620513b6f31a501aa1350c2 (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
from utils.db import dawn_engine, serenitas_engine
import datetime
from pandas.tseries.offsets import BDay
from pyisda.date import default_accrual, previous_twentieth
from analytics.index import CreditIndex
from copy import copy


def get_outstanding_positions(trade_date, fcm):
    r = dawn_engine.execute(
        "SELECT security_id, notional, folder, nextredindexcode, currency, "
        "maturity, indexfactor "
        "FROM list_cds_positions_by_strat_fcm(%s, %s) a "
        "JOIN index_version_markit "
        "ON a.security_id=index_version_markit.redindexcode "
        "WHERE nextredindexcode IS NOT NULL",
        (trade_date, fcm),
    )
    return r


def default_adjustment(company_id, end_date):
    r = serenitas_engine.execute(
        "SELECT recovery, event_date, auction_date FROM defaulted " "WHERE id=%s",
        (company_id,),
    )
    recovery, event_date, auction_date = next(r)
    fee = 1 - recovery
    start_date = previous_twentieth(event_date)
    accrual_days, _ = default_accrual(
        auction_date, event_date, start_date, end_date, 1.0, 1.0
    )
    return accrual_days, fee


PORTFOLIO = {
    "HYOPTDEL": "OPTIONS",
    "HEDGE_MBS": "MORTGAGES",
    "HYINX": "TRANCHE",
    "SER_IGCURVE": "CURVE",
}


def rebook(trade_date, company_id, fcm):
    upfront_settle_date = trade_date + 3 * BDay()
    effective_date = trade_date + datetime.timedelta(days=1)
    for r in get_outstanding_positions(trade_date, fcm):
        accrual_days, fee = default_adjustment(company_id, r["maturity"])
        index_new = CreditIndex(
            redcode=r["nextredindexcode"],
            maturity=r["maturity"],
            value_date=trade_date,
            notional=r["notional"],
        )

        adj = (
            (fee - accrual_days * index_new.fixed_rate * 1e-4 / 360)
            * r["notional"]
            * (r["indexfactor"] - index_new.factor)
        )
        index_new.mark()
        trade_new = {
            "action": "NEW",
            "portfolio": PORTFOLIO[r["folder"]],
            "folder": r["folder"],
            "cp_code": "CONTRA",
            "custodian": "NONE",
            "trade_date": trade_date,
            "effective_date": effective_date,
            "maturity": r["maturity"],
            "currency": r["currency"],
            "payment_rolldate": "Following",
            "notional": abs(r["notional"]),
            "fixed_rate": index_new.fixed_rate / 100,
            "day_count": "ACT/360",
            "frequency": 4,
            "protection": index_new.direction,
            "security_id": r["nextredindexcode"],
            "security_desc": f"CDX {index_new.index_type} CDSI S{index_new.series} 5Y",
            "upfront": index_new.pv,
            "upfront_settle_date": upfront_settle_date,
            "swap_type": "CD_INDEX",
            "account_code": fcm,
        }
        trade_prev = copy(trade_new)
        trade_prev["protection"] = (
            "Seller" if trade_new["protection"] == "Buyer" else "Buyer"
        )
        trade_prev["upfront"] = adj - index_new.pv
        trade_prev["security_id"] = r["security_id"]
        sql_str = (
            f"INSERT INTO cds({','.join(trade_new.keys())}) "
            f"VALUES({','.join(['%s'] * len(trade_new))})"
        )
        dawn_engine.execute(sql_str, [trade_prev.values(), trade_new.values()])


if __name__ == "__main__":
    # PKD
    # rebook(datetime.date(2019, 1, 24), 101148)
    # WINDSSE
    # rebook(datetime.date(2019, 4, 8), 36806879)
    # WFT
    rebook(datetime.date(2019, 7, 26), 103633, "WF")
    rebook(datetime.date(2019, 7, 26), 103633, "BAML")