aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/report_ops/misc.py11
-rw-r--r--python/report_ops/sma.py76
-rw-r--r--python/sma_positions.py27
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)