diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/report_ops/misc.py | 11 | ||||
| -rw-r--r-- | python/report_ops/sma.py | 76 | ||||
| -rw-r--r-- | python/sma_positions.py | 27 |
3 files changed, 114 insertions, 0 deletions
diff --git a/python/report_ops/misc.py b/python/report_ops/misc.py index 7610c9e2..7a787063 100644 --- a/python/report_ops/misc.py +++ b/python/report_ops/misc.py @@ -19,6 +19,17 @@ _recipients = { ), "BAML_FCM": ("footc_margin_csr_amrs@bofa.com",), "NYOPS": ("nyops@lmcg.com",), + "HM": ( + "HM-InnocapFunds@bnymellon.com", + "Vera.Dvorski@bnymellon.com", + "Diana.WuChen@bnymellon.com", + ), +} + +_cc_recipients = { + "ISOSEL": ("selene-ops@lmcg.com",), + "BOWDST": ("bowdoin-ops@lmcg.com",), + "SERCGMAST": ("nyops@lmcg.com"), } diff --git a/python/report_ops/sma.py b/python/report_ops/sma.py new file mode 100644 index 00000000..30a993d4 --- /dev/null +++ b/python/report_ops/sma.py @@ -0,0 +1,76 @@ +import datetime +from dataclasses import dataclass +from serenitas.utils.db import dbconn +from serenitas.utils.exchange import ExchangeMessage +from .misc import _recipients, _cc_recipients +from exchangelib import FileAttachment +import pandas as pd +from io import StringIO +from typing import ClassVar + + +@dataclass +class SMA: + date: datetime.date + fund: str + _em: ClassVar = ExchangeMessage() + + def __init_subclass__(cls, fund): + cls.fund = fund + + def __init__(self, date): + self.date = date + + def get_positions(self): + dawndb = dbconn("dawndb") + df_blotter = pd.read_sql_query( + "SELECT * FROM risk_positions(%s, NULL, %s)", + dawndb, + params=(self.date, self.fund), + index_col=["identifier"], + ) + + cds_positions = pd.read_sql_query( + "SELECT * FROM list_cds_marks_pre(%s, NULL, %s)", + dawndb, + params=(self.date, self.fund), + index_col=["security_id"], + ) + tranche_positions = pd.read_sql_query( + "SELECT id, security_id, security_desc, maturity, a.notional, " + "protection, orig_attach, orig_detach, tranche_factor, clean_nav, " + "accrued, cp_code, cpty_id from list_cds(%s, %s) a " + "LEFT JOIN tranche_risk ON id=tranche_id AND date=%s " + "WHERE orig_attach IS NOT NULL", + dawndb, + params=(self.date, self.fund, self.date), + index_col=["id"], + ) + return df_blotter, cds_positions, tranche_positions + + def email_positions(self): + attachments = [] + for name, df in zip(("bonds", "cds", "tranches"), (self.get_positions())): + buf = StringIO() + df.to_csv(buf) + attachments.append( + FileAttachment( + name=f"{self.date} {name}.csv", content=buf.getvalue().encode() + ) + ) + buf.close() + self._em.send_email( + f"{self.fund} {self.date} EOD positions ", + "", + to_recipients=_recipients["HM"], + cc_recipients=("bowdoin-ops@lmcg.com",), + attach=_cc_recipients[self.fund], + ) + + +class IsoselSMA(SMA, fund="ISOSEL"): + pass + + +class BowdstSMA(SMA, fund="BOWDST"): + pass diff --git a/python/sma_positions.py b/python/sma_positions.py new file mode 100644 index 00000000..de1665e5 --- /dev/null +++ b/python/sma_positions.py @@ -0,0 +1,27 @@ +from report_ops.sma import IsoselSMA, BowdstSMA +import datetime +from serenitas.analytics.dates import prev_business_day +import logging + +logger = logging.getLogger(__name__) +if __name__ == "__main__": + import argparse + + parser = argparse.ArgumentParser() + parser.add_argument( + "date", + nargs="?", + type=datetime.date.fromisoformat, + default=prev_business_day(datetime.date.today()), + help="work date", + ) + args = parser.parse_args() + for sma_cls in ( + IsoselSMA, + BowdstSMA, + ): + sma = sma_cls(args.date) + try: + sma.email_positions() + except ValueError as e: + logger.warning(e) |
