diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/lmcg_monitor.py | 17 | ||||
| -rw-r--r-- | python/report_ops/utils.py | 38 |
2 files changed, 54 insertions, 1 deletions
diff --git a/python/lmcg_monitor.py b/python/lmcg_monitor.py index ea39ebb3..5f8230cd 100644 --- a/python/lmcg_monitor.py +++ b/python/lmcg_monitor.py @@ -3,6 +3,7 @@ import argparse from serenitas.analytics.dates import prev_business_day from serenitas.utils.db import dbconn from serenitas.utils.exchange import ExchangeMessage +from report_ops.utils import CDXNotionalMonitor def monitor_scotia(date, conn): @@ -19,6 +20,20 @@ def monitor_scotia(date, conn): ) +def monitor_cds_notional(fund, date, conn): + with conn.cursor() as c: + c.execute( + "SELECT *, notional as serenitas_notional, globeop_notional / factor as admin_notional FROM list_cds_marks(%s, NULL, %s) WHERE abs((notional * factor) - globeop_notional) > 100;", + (date, fund), + ) + for row in c: + d = row._asdict() + d["difference"] = d["serenitas_notional"] - d["globeop_notional"] + CDXNotionalMonitor.stage(d) + CDXNotionalMonitor.email(fund) + CDXNotionalMonitor._staging_queue.clear() + + if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument( @@ -31,3 +46,5 @@ if __name__ == "__main__": args = parser.parse_args() conn = dbconn("dawndb") monitor_scotia(args.cob, conn) + for fund in ("SERCGMAST", "BOWDST", "ISOSEL"): + monitor_cds_notional(fund, args.cob, conn) diff --git a/python/report_ops/utils.py b/python/report_ops/utils.py index 3b47a50f..035b2e13 100644 --- a/python/report_ops/utils.py +++ b/python/report_ops/utils.py @@ -102,7 +102,7 @@ def check_cleared_cds(date, fund, conn): _tolerance = {"IG": 0.10, "HY": 0.20, "EU": 0.20, "XO": 0.30} with conn.cursor() as c: c.execute( - "SELECT *, abs(price-globeop_price) AS difference FROM list_cds_marks(%s, NULL, %s) WHERE ((notional * factor) - globeop_notional) < 100;", + "SELECT *, abs(price-globeop_price) AS difference FROM list_cds_marks(%s, NULL, %s) WHERE abs((notional * factor) - globeop_notional) < 100;", (date, fund), ) for row in c: @@ -350,6 +350,42 @@ class CDXQuoteMonitor( ) +class CDXNotionalMonitor( + Monitor, + headers=( + "security_desc", + "security_id", + "maturity", + "admin_notional", + "serenitas_notional", + "difference", + ), + num_format=[("{0:,.2f}", 3), ("{0:,.2f}", 4), ("{0:,.2f}", 5)], +): + @classmethod + def email(cls, fund): + if not cls._staging_queue: + return + cls._em.send_email( + f"CDX Notional Mismatches: {fund}", + 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>Mismatched cleared cds notional mismatches below:<br><br>{cls.to_tabulate()} + </body> +</html>""" + ), + to_recipients=_cc_recipients[fund], + ) + + class SettlementMonitor( Monitor, headers=("date", "account", "currency", "projected_balance"), |
