aboutsummaryrefslogtreecommitdiffstats
path: root/python/cds_rebook.py
blob: bb8b3e0cb4e86e97feeed3418418d2c29beab538 (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
from 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):
    r = dawn_engine.execute(
        "SELECT security_id, notional, folder, nextredindexcode, currency, "
        "maturity, indexfactor "
        "FROM list_cds_positions_by_strat(%s) a "
        "JOIN index_version_markit "
        "ON a.security_id=index_version_markit.redindexcode "
        "WHERE nextredindexcode IS NOT NULL",
        (trade_date,))
    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., 1.)
    return accrual_days, fee

PORTFOLIO = {"HYOPTDEL": "OPTIONS",
             "HEDGE_MBS": "MORTGAGES"}

def rebook(trade_date, company_id):
    upfront_settle_date = trade_date + 3 * BDay()
    effective_date = trade_date + datetime.timedelta(days=1)
    for r in get_outstanding_positions(trade_date):
        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': 'INTERCO',
                     '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'}
        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)