aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/lmcg_monitor.py17
-rw-r--r--python/report_ops/utils.py38
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"),