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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
from utils.db import serenitas_pool, dbconn
import datetime
import pandas as pd
from pandas.tseries.offsets import BDay
from psycopg2.extras import execute_values
from pyisda.date import default_accrual, previous_twentieth
from analytics.index import CreditIndex
from copy import copy
def get_outstanding_positions(conn, trade_date, fcm, fund="SERCGMAST"):
with conn.cursor() as c:
c.execute(
"SELECT security_id, notional, folder, nextredindexcode, currency, "
"maturity, indexfactor "
"FROM list_cds_positions_by_strat_fcm(%s, %s, %s) a "
"JOIN index_version_markit "
"ON a.security_id=index_version_markit.redindexcode "
"WHERE nextredindexcode IS NOT NULL AND nextredindexcode !='2I65BRUV0'",
(trade_date, fcm, fund),
)
yield from c
def default_adjustment(conn, company_id, seniority, end_date):
with conn.cursor() as c:
c.execute(
"SELECT recovery, event_date, auction_date FROM defaulted WHERE id=%s "
"AND seniority=%s",
(company_id, seniority),
)
recovery, event_date, auction_date = next(c)
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",
"HEDGE_CLO": "CLO",
}
def rebook(conn, trade_date, company_id, seniority, fcm, fund="SERCGMAST"):
dawndb = dbconn("dawndb")
upfront_settle_date = trade_date + 3 * BDay()
effective_date = trade_date + datetime.timedelta(days=1)
for r in get_outstanding_positions(dawndb, trade_date, fcm, fund):
accrual_days, fee = default_adjustment(conn, company_id, seniority, 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 = {
"fund": fund,
"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())}) VALUES %s"
with dawndb.cursor() as c:
execute_values(
c, sql_str, [tuple(trade_prev.values()), tuple(trade_new.values())]
)
dawndb.commit()
dawndb.close()
def insert_newids(dawndb, d: datetime.date, df: pd.DataFrame):
with dawndb.cursor() as c:
c.execute(
"INSERT INTO id_mapping ( "
" SELECT %s, 'CDS', serenitas_id, new_id FROM ( "
" SELECT * FROM unnest(%s, %s) AS t(globeop_id, new_id) "
" LEFT JOIN id_mapping USING (globeop_id)) a"
")",
(d, df.old_ids.tolist(), df.new_ids.to_list()),
)
dawndb.commit()
if __name__ == "__main__":
conn = serenitas_pool.getconn()
# 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")
# DF
# rebook(datetime.date(2019, 12, 11), 154954, "Senior", "BAML")
# MNI
# rebook(datetime.date(2020, 3, 13), 100957, "Senior", "BAML")
# rebook(datetime.date(2020, 3, 13), 100957, "Senior", "WF")
# WLL
# rebook(datetime.date(2020, 5, 7), 8240322, "Senior", "BAML")
# rebook(datetime.date(2020, 5, 7), 8240322, "Senior", "WF")
# rebook(conn, datetime.date(2020, 5, 7), 8240322, "Senior", "GS", "BOWDST")
# FCA
rebook(conn, datetime.date(2020, 5, 14), 100337, "Senior", "BAML")
rebook(conn, datetime.date(2020, 5, 14), 100337, "Senior", "WF")
rebook(conn, datetime.date(2020, 5, 14), 100337, "Senior", "GS", "BOWDST")
serenitas_pool.putconn(conn)
|