diff options
Diffstat (limited to 'python/trade_dataclasses.py')
| -rw-r--r-- | python/trade_dataclasses.py | 83 |
1 files changed, 79 insertions, 4 deletions
diff --git a/python/trade_dataclasses.py b/python/trade_dataclasses.py index dabfe05f..7b80a103 100644 --- a/python/trade_dataclasses.py +++ b/python/trade_dataclasses.py @@ -1,8 +1,8 @@ from dataclasses import dataclass, field, fields, Field from enum import Enum from io import StringIO -from headers import DealType, MTM_HEADERS -from typing import ClassVar +from headers import DealType, MTM_HEADERS, HEADERS +from typing import ClassVar, Tuple, Union from decimal import Decimal from typing import Literal import csv @@ -21,6 +21,8 @@ from serenitas.utils.remote import SftpClient from lru import LRU from psycopg.errors import UniqueViolation import logging +from serenitas.utils.remote import FtpClient, SftpClient + logger = logging.getLogger(__name__) Fund = Literal["SERCGMAST", "BRINKER", "BOWDST"] @@ -191,6 +193,56 @@ class DealKind: return None +def get_admin_headers(fund, trade_type): + if fund in ("SERCGMAST", "BOWDST", "BRINKER"): + return HEADERS[trade_type] + + +def get_fname( + trade_type: Union[str, Tuple[str, str]], + fund: str = "SERCGMAST", +): + d = { + "bond": "Mortgages", + "cds": "CreditDefaultSwapDeal", + "swaption": "SwaptionDeal", + "future": "Future", + "wire": "CashFlowDeal", + "spot": "SpotDeal", + "fx_swap": "FxSwapDeal", + "capfloor": "CapFloor", + "repo": "RepoDeal", + "termination": "Termination", + } + 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() + if fund == "BRINKER": + return f"LMCG_BBH_SWAP_TRADES_P.{timestamp:%Y%m%d%H%M%S}.csv" + elif fund == "SERCGMAST": + return f"Serenitas.ALL.{timestamp:%Y%m%d.%H%M%S}.{trade_tag}.csv" + elif fund == "BOWDST": + return f"Bowdst.ALL.{timestamp:%Y%m%d.%H%M%S}.{trade_tag}.csv" + + +def upload_buf(buf, dest, fund): + match fund: + case "SERCGMAST": + ftp = FtpClient.from_creds("globeop") + ftp.client.cwd("incoming") + ftp.put(buf, dest) + case "BOWDST": + sftp = SftpClient.from_creds("hm_globeop") + sftp.put(buf, dest) + case "BRINKER": + sftp = SftpClient.from_creds("bbh") + sftp.put(buf, dest) + + class Deal: _conn: ClassVar = dbconn("dawndb", application_name="autobooker") _registry = {} @@ -199,6 +251,7 @@ class Deal: _sql_insert: ClassVar[str] _sql_select: ClassVar[str] _insert_queue: ClassVar[list] = [] + _admin_queue: ClassVar[list] = [] def __class_getitem__(cls, deal_type: DealType): return cls._registry[deal_type] @@ -228,6 +281,28 @@ class Deal: ) @classmethod + def admin_upload(cls, fund, trade_type, upload): + if not cls._admin_queue: # early exit + return + buf = StringIO() + csvwriter = csv.writer(buf) + headers = get_admin_headers(fund, trade_type) + csvwriter.writerow(headers) + csvwriter.writerows( + [row.get(h, None) for h in headers] for row in cls._admin_queue + ) + buf = buf.getvalue().encode() + fname = get_fname(trade_type, fund) + dest = DAILY_DIR / str(datetime.date.today()) / fname + dest.parent.mkdir(exist_ok=True) + dest.write_bytes(buf) + if upload: + upload_buf(buf, fname, fund) + + def admin_stage(self): + self._admin_queue.append(self.to_admin()) + + @classmethod def commit(cls): with cls._conn.cursor() as c: c.executemany(cls._sql_insert, cls._insert_queue) @@ -588,7 +663,7 @@ class TerminationDeal( ) id: int = field(default=None, metadata={"insert": False}) dealid: str = field(default=None, metadata={"insert": False, "mtm": "Swap ID"}) - factor: float = field(default=1, metadata={"insert": False}) + factor: float = field(init=False, default=1, metadata={"insert": False}) orig_cp: str = field( init=False, metadata={"mtm": "Remaining Party", "insert": False}, @@ -662,7 +737,7 @@ class TerminationDeal( obj["Product Type"] = obj["product_type"] return obj - def to_globeop(self): + def to_admin(self): obj = self.serialize("globeop") obj["TerminationAmount"] *= self.factor obj["FeesPaid"] = ( |
