aboutsummaryrefslogtreecommitdiffstats
path: root/python/notify_bowdst.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/notify_bowdst.py')
-rw-r--r--python/notify_bowdst.py201
1 files changed, 106 insertions, 95 deletions
diff --git a/python/notify_bowdst.py b/python/notify_bowdst.py
index 76d6d0f4..ca987a03 100644
--- a/python/notify_bowdst.py
+++ b/python/notify_bowdst.py
@@ -12,109 +12,120 @@ import argparse
import numpy as np
import sys
-parser = argparse.ArgumentParser(description="determine sender destination")
-parser.add_argument("--globeop", action="store_true", help="send to globeop")
-parser.add_argument(
- "--debug", "-d", action="store_true", default=False, help="log to the console"
-)
-args = parser.parse_args()
+def send_email(inaccurate_balances, accurate_balances, logger, conn, cob, args):
+ for row in inaccurate_balances.itertuples():
+ subject = f"ACTION REQUESTED: Missing Trades {row.Index} RED: {row.security_id}"
+ try:
+ last_date = accurate_balances.xs(row.Index, level="security_desc").index[-1]
-if args.debug:
- logging.basicConfig()
-
-logger = logging.getLogger(__name__)
-if not logger.handlers:
- fh = SerenitasFileHandler("mismatched_trades.log")
- logger.addHandler(fh)
-logger.setLevel(logging.INFO)
-
-conn = dbconn("dawndb")
-cob = (datetime.date.today() - BDay(1)).date()
-dates = pd.date_range(end=cob, periods=50)
-df = pd.concat(
- [
- pd.read_sql_query(
- "SELECT *, notional * factor AS db_notional "
- "FROM list_cds_marks(%s, NULL, 'BOWDST')",
+ except IndexError:
+ logger.warning(f"No matches for {row.security_desc}")
+ continue
+ buf = StringIO()
+ output = pd.read_sql_query(
+ "SELECT * FROM cds WHERE trade_date > %s and trade_date <= %s "
+ "AND fund = 'BOWDST' AND security_desc = %s "
+ "AND orig_detach IS NULL AND orig_attach IS NULL ORDER BY trade_date DESC",
conn,
- params=(d,),
- index_col=["security_desc"],
+ params=(last_date, cob, row.Index),
)
- for d in dates.date
- ],
- keys=dates,
-)
-
-mask = np.isclose(df.globeop_notional, df.db_notional, atol=1e-2, rtol=0.0)
+ if not output[output.trade_date >= cob - BDay(1)].empty:
+ logger.warning(
+ f"Mismatch balance {row.Index} {row.globeop_notional} :{row.db_notional} Trades Recently"
+ )
+ continue
+ output.to_csv(buf, index=False)
+ attachments = [
+ FileAttachment(name=f"{row.Index}.csv", content=buf.getvalue().encode())
+ ]
+ buf.close()
+ msg = (
+ "Good morning,\n\n"
+ f"We notice a difference in our notional ({row.db_notional:,.2f}) versus yours ({row.globeop_notional:,.2f}) "
+ f"for security {row.Index} RED: {row.security_id}.\n"
+ f"Our notionals last matched on {last_date} for ${row.globeop_notional:,.2f}.\n\n"
+ "Please see attached all the trades since we last matched. Please ensure they match your data.\n\n"
+ "Thanks for your help!\n\n"
+ "Flint"
+ )
+ em = ExchangeMessage()
+ if args.globeop:
+ recipients = (
+ "caagtradecapture@bnymellon.com",
+ "hm-operations@bnymellon.com",
+ "caagprim@bnymellon.com",
+ "julie.picariello@bnymellon.com",
+ "sa1futures.optionsprocessing@bnymellon.com",
+ )
+ cc_recipients = (
+ "fyu@lmcg.com",
+ "Bowdoin-Ops@LMCG.com",
+ )
+ else:
+ recipients = ("fyu@lmcg.com",)
+ cc_recipients = ()
-try:
- inaccurate_balances = df[~mask].loc[
- pd.Timestamp(cob), ["tenor", "security_id", "globeop_notional", "db_notional"]
- ]
-except KeyError:
- logger.info("All Balances Matching")
- sys.exit()
-accurate_balances = df[mask]
+ em.send_email(
+ subject,
+ msg,
+ to_recipients=recipients,
+ cc_recipients=cc_recipients,
+ attach=attachments,
+ )
-for row in inaccurate_balances.itertuples():
- subject = f"ACTION REQUESTED: Missing Trades {row.Index} RED: {row.security_id}"
- try:
- last_date = accurate_balances.xs(row.Index, level="security_desc").index[-1]
- except IndexError:
- logger.warning(f"No matches for {row.security_desc}")
- continue
- buf = StringIO()
- output = pd.read_sql_query(
- "SELECT * FROM cds WHERE trade_date > %s and trade_date <= %s "
- "AND fund = 'BOWDST' AND security_desc = %s "
- "AND orig_detach IS NULL AND orig_attach IS NULL ORDER BY trade_date DESC",
- conn,
- params=(last_date, cob, row.Index),
- )
- if not output[output.trade_date >= cob - BDay(1)].empty:
- logger.warning(
- f"Mismatch balance {row.Index} {row.globeop_notional} :{row.db_notional} Trades Recently"
- )
- continue
- output.to_csv(buf, index=False)
- attachments = [
- FileAttachment(name=f"{row.Index}.csv", content=buf.getvalue().encode())
- ]
- buf.close()
- msg = (
- "Good morning,\n\n"
- f"We notice a difference in our notional ({row.db_notional:,.2f}) versus yours ({row.globeop_notional:,.2f}) "
- f"for security {row.Index} RED: {row.security_id}.\n"
- f"Our notionals last matched on {last_date} for ${row.globeop_notional:,.2f}.\n\n"
- "Please see attached all the trades since we last matched. Please ensure they match your data.\n\n"
- "Thanks for your help!\n\n"
- "Flint"
+def main():
+ parser = argparse.ArgumentParser(description="determine sender destination")
+ parser.add_argument("--globeop", action="store_true", help="send to globeop")
+ parser.add_argument(
+ "--debug", "-d", action="store_true", default=False, help="log to the console"
)
- em = ExchangeMessage()
- if args.globeop:
- recipients = (
- "caagtradecapture@bnymellon.com",
- "hm-operations@bnymellon.com",
- "caagprim@bnymellon.com",
- "julie.picariello@bnymellon.com",
- "sa1futures.optionsprocessing@bnymellon.com",
- )
- cc_recipients = (
- "fyu@lmcg.com",
- "Bowdoin-Ops@LMCG.com",
- )
- else:
- recipients = ("fyu@lmcg.com",)
- cc_recipients = ()
- em.send_email(
- subject,
- msg,
- to_recipients=recipients,
- cc_recipients=cc_recipients,
- attach=attachments,
+ args = parser.parse_args()
+
+ if args.debug:
+ logging.basicConfig()
+
+ logger = logging.getLogger(__name__)
+ if not logger.handlers:
+ fh = SerenitasFileHandler("mismatched_trades.log")
+ logger.addHandler(fh)
+ logger.setLevel(logging.INFO)
+
+ conn = dbconn("dawndb")
+ cob = (datetime.date.today() - BDay(1)).date()
+ dates = pd.date_range(end=cob, periods=50)
+ df = pd.concat(
+ [
+ pd.read_sql_query(
+ "SELECT *, notional * factor AS db_notional "
+ "FROM list_cds_marks(%s, NULL, 'BOWDST')",
+ conn,
+ params=(d.date(),),
+ index_col=["security_desc"],
+ )
+ for d in dates
+ ],
+ keys=dates,
)
-logger.info("Program executed.")
+ mask = np.isclose(df.globeop_notional, df.db_notional, atol=1e-2, rtol=0.0)
+
+ try:
+ inaccurate_balances = df[~mask].loc[
+ pd.Timestamp(cob),
+ ["tenor", "security_id", "globeop_notional", "db_notional"],
+ ]
+ except KeyError:
+ logger.info("All Balances Matching")
+ sys.exit()
+ accurate_balances = df[mask]
+
+ send_email(inaccurate_balances, accurate_balances, logger, conn, cob, args)
+
+ logger.info("Program executed.")
+
+
+if __name__ == "__main__":
+ main()