aboutsummaryrefslogtreecommitdiffstats
path: root/python/ops/funds.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/ops/funds.py')
-rw-r--r--python/ops/funds.py114
1 files changed, 114 insertions, 0 deletions
diff --git a/python/ops/funds.py b/python/ops/funds.py
new file mode 100644
index 00000000..bfc3750d
--- /dev/null
+++ b/python/ops/funds.py
@@ -0,0 +1,114 @@
+import csv
+import datetime
+import pathlib
+from serenitas.utils.remote import FtpClient, SftpClient
+from serenitas.utils.exchange import ExchangeMessage, FileAttachment
+from io import StringIO
+from typing import Tuple, Union
+
+
+class Fund:
+ staged_queue = []
+ _registry = {}
+ filepath_pattern = None
+
+ def __class_getitem__(cls, fund_name: str):
+ return cls._registry[fund_name]
+
+ def __init_subclass_(cls, fund_name: str):
+ cls.name = fund_name
+ cls._registry[fund_name] = cls
+
+ @classmethod
+ def build_buffer(cls, trade_type):
+ buf = StringIO()
+ csvwriter = csv.writer(buf)
+ csvwriter.writerow(get_headers(trade_type, cls.name))
+ csvwriter.writerows(cls.staged_queue)
+ buf = buf.getvalue().encode()
+ dest = cls.get_filepath(DAILY_DIR, trade_type)
+ dest.parent.mkdir(exist_ok=True)
+ dest.write_bytes(buf)
+ return buf, dest
+
+ @classmethod
+ def set_headers(cls, trade_type):
+ cls.headers = get_headers(trade_type, cls.name)
+
+ @classmethod
+ def stage(cls, trade, trade_type):
+ cls.staged_queue.append(build_line(trade, trade_type, cls.name))
+
+ @classmethod
+ def get_filepath(
+ cls,
+ base_dir: pathlib.Path,
+ trade_type: Union[str, Tuple[str, str]],
+ ) -> pathlib.Path:
+ d = {
+ "bond": "Mortgages",
+ "cds": "CreditDefaultSwapDeal",
+ "swaption": "SwaptionDeal",
+ "future": "Future",
+ "wire": "CashFlowDeal",
+ "spot": "SpotDeal",
+ "fx_swap": "FxSwapDeal",
+ "capfloor": "CapFloor",
+ "repo": "RepoDeal",
+ }
+ trade_tag: str
+ if isinstance(trade_type, tuple):
+ trade_tag = d[trade_type[0]] + trade_type[1]
+ else:
+ trade_tag = d[trade_type]
+
+ timestamp = datetime.datetime.now()
+ return (
+ base_dir
+ / str(timestamp.date())
+ / cls.filepath_pattern.format(timestamp, trade_tag)
+ )
+
+
+class Serenitas(Fund, fund_name="SERCGMAST"):
+ filepath_pattern = "Serenitas.ALL.{timestamp:%Y%m%d.%H%M%S}.{trade_tag}.csv"
+
+ @staticmethod
+ def upload(buf, dest):
+ ftp = FtpClient.from_creds("serenitas")
+ ftp.client.cwd("incoming")
+ ftp.client.put(buf, dest)
+
+
+class Brinker(Fund, fund_name="BRINKER"):
+ filepath_pattern = "LMCG_BBH_SWAP_TRADES_P.{timestamp:%Y%m%d%H%M%S}.csv"
+
+ @staticmethod
+ def upload(buf, dest):
+ sftp = SftpClient.from_creds("bbh")
+ sftp.put(buf, dest)
+
+
+class Bowdst(Fund, fund_name="BOWDST"):
+ filepath_pattern = "Bowdst.ALL.{timestamp:%Y%m%d.%H%M%S}.{trade_tag}.csv"
+
+ @staticmethod
+ def upload(buf, dest):
+ sftp = SftpClient.from_creds("hm_globeop")
+ sftp.client.chdir("incoming")
+ sftp.put(buf, dest)
+ em = ExchangeMessage()
+ recipients = ("hm-operations@bnymellon.com",)
+ em.send_email(
+ "Trade file",
+ "",
+ to_recipients=recipients,
+ cc_recipients=("bowdoin-ops@lmcg.com",),
+ attach=(FileAttachment(name=dest, content=buf),),
+ )
+
+
+class Selene(Fund, fund_name="ISOSEL"):
+ @classmethod
+ def stage(cls, trade, action="NEW"):
+ cls.staged_queue.append(trade.to_citco(action))