diff options
Diffstat (limited to 'python/trade_dataclasses.py')
| -rw-r--r-- | python/trade_dataclasses.py | 82 |
1 files changed, 78 insertions, 4 deletions
diff --git a/python/trade_dataclasses.py b/python/trade_dataclasses.py index 6f50ecc9..a8331d29 100644 --- a/python/trade_dataclasses.py +++ b/python/trade_dataclasses.py @@ -12,6 +12,7 @@ from serenitas.utils.db2 import dbconn from lru import LRU from psycopg.errors import UniqueViolation import logging +from utils import rename_keys logger = logging.getLogger(__name__) Fund = Literal["SERCGMAST", "BRINKER", "BOWDST"] @@ -191,6 +192,7 @@ class DealType(Enum): Bond = "BOND" CDS = "CDX" Swaption = "SWAPTION" + Termination = "TERM" class Deal: @@ -205,16 +207,19 @@ class Deal: def __class_getitem__(cls, deal_type: DealType): return cls._registry[deal_type] - def __init_subclass__(cls, deal_type: DealType, table_name: str, insert_ignore=()): + def __init_subclass__( + cls, deal_type: DealType, table_name: str, insert_ignore=(), select_ignore=() + ): super().__init_subclass__() cls._registry[deal_type] = cls cls._table_name = table_name insert_columns = [c for c in cls.__annotations__ if c not in insert_ignore] - place_holders = ",".join(["%s"] * len(insert_columns)) + insert_place_holders = ",".join(["%s"] * len(insert_columns)) + select_columns = [c for c in cls.__annotations__ if c not in select_ignore] - cls._sql_insert = f"INSERT INTO {cls._table_name}({','.join(insert_columns)}) VALUES({place_holders})" + cls._sql_insert = f"INSERT INTO {cls._table_name}({','.join(insert_columns)}) VALUES({insert_place_holders})" cls._sql_select = ( - f"SELECT {','.join(cls.__annotations__)} FROM {cls._table_name} WHERE id=%s" + f"SELECT {','.join(select_columns)} FROM {cls._table_name} WHERE id=%s" ) def stage(self): @@ -225,6 +230,13 @@ class Deal: if f.metadata.get("insert", True) ] ) + self._select_queue.append( + [ + getattr(self, f.name) + for f in fields(self) + if f.metadata.get("insert", True) + ] + ) @classmethod def commit(cls): @@ -499,3 +511,65 @@ class SwaptionDeal( obj["Strike Price"] = obj["Strike Price"] * 0.01 obj["Effective Date"] = obj["Trade Date"] return obj + + +@dataclass +class TerminationDeal( + Deal, + deal_type=DealType.Termination, + table_name="terminations", + insert_ignore=("id", "dealid", "orig_cp", "currency", "fund", "product_type"), + select_ignore=("orig_cp", "currency", "fund", "product_type"), +): + termination_fee: float = field(metadata={"mtm": "Initial Payment"}) + fee_payment_date: datetime.date = field(metadata={"mtm": "Settle Date"}) + termination_cp: str = field(metadata={"mtm": "Broker Id"}) + termination_amount: float = field(metadata={"mtm": "1st Leg Notional"}) + termination_date: datetime.date = field( + default_factory=datetime.date.today(), metadata={"mtm": "Trade Date"} + ) + id: int = field(default=None, metadata={"insert": False}) + dealid: str = field(default=None, metadata={"insert": False, "mtm": "Swap ID"}) + orig_cp: str = field( + default=None, + metadata={"mtm": "Remaining Party", "insert": False, "select": False}, + ) + currency: str = field( + default=None, + metadata={"mtm": "Currency Code", "insert": False, "select": False}, + ) + fund: str = field( + default=None, + metadata={"mtm": "Account Abbreviation", "insert": False, "select": False}, + ) + product_type: str = field( + default=None, metadata={"mtm": "Product Type", "insert": False, "select": False} + ) + + def __post_init__(self): + with self._conn.cursor() as c: + termination_information = ( + """SELECT coalesce(cds.cp_code, swaptions.cp_code) AS orig_cp, COALESCE (cds.currency, swaptions.currency) AS currency, """ + """COALESCE (cds.swap_type, 'SWAPTION') as product_type, COALESCE (cds.fund, swaptions.fund) as fund FROM terminations LEFT JOIN cds USING (dealid) """ + """LEFT JOIN swaptions USING (dealid) WHERE terminations.id=%s;""" + ) + c.execute(termination_information, (self.id,)) + self.orig_cp, self.currency, self.product_type, self.fund = c.fetchone() + + def to_markit(self): + obj = self.serialize("mtm") + if obj["Initial Payment"] >= 0: + obj["Transaction Code"] = "Receive" + else: + obj["Initial Payment"] = abs(obj["Initial Payment"]) + obj["Transaction Code"] = "Pay" + swap_type = {"CD_INDEX_TRANCHE": "TRN", "SWAPTION": "CDISW"} + obj["Product Type"] = swap_type[obj["Product Type"]] + obj["Trade ID"] = obj["Swap ID"] + "-" + str(obj["id"]) + obj["Transaction Type"] = ( + "Termination" + if obj["Remaining Party"] == obj["Broker Id"] + else "Assignment" + ) + obj["Effective Date"] = obj["Trade Date"] + return obj |
