aboutsummaryrefslogtreecommitdiffstats
path: root/python/trade_dataclasses.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/trade_dataclasses.py')
-rw-r--r--python/trade_dataclasses.py82
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