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 from serenitas.utils.env import DAILY_DIR from .file_gen import get_headers, build_line 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) headers = get_headers(trade_type, cls.name) csvwriter.writerow(headers) csvwriter.writerows( [[obj.get(h) for h in headers] for obj in cls.stating_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, **kwargs): cls.stating_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", **kwargs): cls.stating_queue.append(trade.to_citco(action))