diff options
Diffstat (limited to 'python/notify_bowdst.py')
| -rw-r--r-- | python/notify_bowdst.py | 131 |
1 files changed, 0 insertions, 131 deletions
diff --git a/python/notify_bowdst.py b/python/notify_bowdst.py deleted file mode 100644 index ca987a03..00000000 --- a/python/notify_bowdst.py +++ /dev/null @@ -1,131 +0,0 @@ -from serenitas.utils.db import dbconn -import pandas as pd -from pandas.tseries.offsets import BDay -import datetime -from io import StringIO -from exchangelib import FileAttachment -from serenitas.utils.exchange import ExchangeMessage - -from serenitas.utils import SerenitasFileHandler -import logging -import argparse -import numpy as np -import sys - - -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] - - 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" - ) - 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, - ) - - -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" - ) - - 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, - ) - - 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() |
