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
|
import datetime
import argparse
from exchangelib import HTMLBody
from report_ops.utils import Monitor
from mtm_status import get_latest_file
counterparty_contacts = {
("BAMSNY", "USD"): (
"dg.gcss_usip_mo@bofa.com",
"shalini.goel@bofa.com",
"dtcc.chasing@bofa.com",
"dg.cmbs-mbex_trade_support@bofa.com",
),
("BAMSNY", "EUR"): (
"emea_credit_fo_support@bofa.com",
"dtcc.chasing@bofa.com",
"dg.cmbs-mbex_trade_support@bofa.com",
),
("JPCBNY", "USD"): ("credit.na.affirmations@jpmorgan.com",),
("JPCBNY", "EUR"): ("JPM.creditassignmentseurope@jpmorgan.com",),
("MSCSNY", "USD"): ("msnovationsteam@morganstanley.com",),
("GOLDNY", "USD"): (
"Navneet.Sawant@gs.com",
"Vishal.Kanojia@ny.email.gs.com",
"NY-CDMO@ny.email.gs.com",
),
("GOLDNY", "EUR"): (
"Navneet.Sawant@gs.com",
"Vishal.Kanojia@ny.email.gs.com",
"LDNCDMO@gs.com",
),
("CITINY", "USD"): (
"citiassignmentsus@citigroup.com",
"james.b.okun@citi.com",
),
("CITINY", "EUR"): (
"citiassignmentsus@citigroup.com",
"aaron.beasant@citi.com",
),
("BNPBNY", "USD"): ("LM_Sales_Assistants@US.BNPParibas.com",),
("BNPBNY", "EUR"): ("CDSnovationsEurope@bnpparibas.com",),
}
class CreditNovationsMonitor(
Monitor,
headers=(
"date",
"ncm_id",
"EE",
"RP",
"currency",
),
num_format=[],
):
@classmethod
def email(cls, date, contacts):
if not cls._staging_queue:
return
cls._em.send_email(
f"*ACTION REQUESTED* Unconsented Novations Due Today {date}",
HTMLBody(
f"""
<html>
<head>
<style>
table, th, td {{ border: 1px solid black; border-collapse: collapse;}}
th, td {{ padding: 5px; }}
</style>
</head>
<body>
Good morning,<br><br>We have the below novations expiring today. Could you please consent or provide us an update on the novations?<br><br>{cls.to_tabulate()}
</body>
</html>"""
),
to_recipients=contacts,
cc_recipients=("NYOPs@lmcg.com",),
reply_to=("NYOPs@lmcg.com",),
)
def contact_novation_counterparties(date):
df = get_latest_file(date)
df = df[
(df["SwapType"].isin(["ASGM"]))
& (df["ThirdPartyStatus.1"].isin(["Pending Consent"]))
]
df = (
df.groupby(
["ExecutingBroker", "RemainingBroker", "CurrencyCode"], group_keys=False
)["Novation Consent ID"]
.apply(list)
.reset_index()
)
for row in df.itertuples():
d = {
"date": date,
"currency": row.CurrencyCode,
"EE": row.ExecutingBroker,
"RP": row.RemainingBroker,
}
contacts = (
counterparty_contacts[(row.ExecutingBroker, row.CurrencyCode)]
+ counterparty_contacts[(row.RemainingBroker, row.CurrencyCode)]
)
for novationid in row[4]:
CreditNovationsMonitor.stage(d | {"ncm_id": novationid})
CreditNovationsMonitor.email(date, contacts)
CreditNovationsMonitor.clear()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument(
"date",
type=datetime.date.fromisoformat,
default=datetime.date.today(),
nargs="?",
)
args = parser.parse_args()
contact_novation_counterparties(args.date)
|