diff options
Diffstat (limited to 'python/ops/funds.py')
| -rw-r--r-- | python/ops/funds.py | 114 |
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)) |
