diff options
| -rw-r--r-- | python/book_bbg.py | 49 | ||||
| -rw-r--r-- | python/trade_dataclasses.py | 48 |
2 files changed, 50 insertions, 47 deletions
diff --git a/python/book_bbg.py b/python/book_bbg.py index 4856ae5d..e12646cb 100644 --- a/python/book_bbg.py +++ b/python/book_bbg.py @@ -1,52 +1,16 @@ from serenitas.utils.remote import SftpClient -import datetime +from trade_dataclasses import Deal, DealType, BbgDeal import csv -from trade_dataclasses import CDSDeal, BondDeal, BbgDeal, _funds, _cdx_cp, _fcms -from decimal import Decimal from stat import S_ISREG -def get_indic_data(conn, redcode, tenor): - sql_str = ( - "SELECT maturity, coupon " - "FROM index_desc " - "WHERE tenor=%s AND redindexcode=%s " - ) - with conn.cursor() as c: - c.execute(sql_str, (redcode, tenor)) - return c.fetchone() - - -def cdx_booking_process(path, conn): - reader = csv.DictReader(path) - for line in reader: - trade = CDSDeal( - fund=_funds[line["Account"]], - folder="*", - portfolio="UNALLOCATED", - security_id=line["Red Code"], - security_desc=line["Security"].removesuffix(" PRC"), - traded_level=Decimal(line["Price (Dec)"]), - notional=line["Quantity"], - fixed_rate=float(line["Coupon"]) * 0.01, - trade_date=datetime.datetime.strptime(line["Trade Dt"], "%m/%d/%Y").date(), - maturity=datetime.datetime.strptime(line["Mat Dt"], "%m/%d/%Y").date(), - currency=line["Curncy"], - protection="Buyer" if line["Side"] == "B" else "Seller", - upfront=line["Principal"], - cp_code=_cdx_cp[line["Brkr"]], - account_code=_fcms[line["Client FCM"]], - ) - trade.stage() - CDSDeal.commit() - - -def bond_booking_process(file_handle, index): +def trade_booking_process(file_handle, index, asset_class): + deal = Deal[DealType(asset_class)] for row in csv.DictReader(file_handle): line = {"bbg_ticket_id": index, **row} - trade = BondDeal.from_bbg_line(line) + trade = deal.from_bbg_line(line) trade.stage() - BondDeal.commit() + deal.commit() def get_bbg_id(name): @@ -56,14 +20,13 @@ def get_bbg_id(name): if __name__ == "__main__": import time - booker = {"BOND": bond_booking_process, "CDX": cdx_booking_process} sftp = SftpClient.from_creds("bbg") while True: for f in sftp.client.listdir_iter("/"): if S_ISREG(f.st_mode): if (bbg_id := get_bbg_id(f.filename)) not in BbgDeal._cache: with sftp.client.open(f.filename) as fh: - booker[f.filename.split("-", 1)[0]](fh, bbg_id) + trade_booking_process(fh, bbg_id, f.filename.split("-", 1)[0]) BbgDeal._cache[bbg_id] = None time.sleep(60) diff --git a/python/trade_dataclasses.py b/python/trade_dataclasses.py index b6e14313..6310dc40 100644 --- a/python/trade_dataclasses.py +++ b/python/trade_dataclasses.py @@ -149,16 +149,26 @@ class Counterparty: register_adapter(Frequency, lambda f: AsIs(f.value)) +class DealType(Enum): + Bond = "BOND" + CDS = "CDX" + + class Deal: _conn: ClassVar = dbconn("dawndb", application_name="autobooker") + _registry = {} _table_name: None _sql_fields: ClassVar[list[str]] _sql_insert: ClassVar[str] _sql_select: ClassVar[str] _insert_queue: ClassVar[list] = [] - def __init_subclass__(cls, table_name: str, insert_ignore=()): + def __class_getitem__(cls, deal_type: DealType): + return cls._registry[deal_type] + + def __init_subclass__(cls, deal_type: DealType, table_name: str, insert_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)) @@ -210,7 +220,7 @@ class BbgDeal: ) elif cls.__name__ == "CDSDeal": cls._bbg_sql_insert = ( - f"INSERT INTO cds_tickets VALUES({','.join(['%s'] * 20)})" + f"INSERT INTO cds_tickets VALUES({','.join(['%s'] * 22)})" ) @classmethod @@ -230,7 +240,13 @@ class BbgDeal: @dataclass -class CDSDeal(BbgDeal, Deal, table_name="cds", insert_ignore=("id", "dealid")): +class CDSDeal( + BbgDeal, + Deal, + deal_type=DealType.CDS, + table_name="cds", + insert_ignore=("id", "dealid"), +): fund: Fund = field(metadata={"mtm": "Account Abbreviation"}) account_code: str cp_code: str = field(metadata={"mtm": "Broker Id"}) @@ -263,6 +279,7 @@ class CDSDeal(BbgDeal, Deal, table_name="cds", insert_ignore=("id", "dealid")): isda_definition: IsdaDoc = "ISDA2014" id: int = field(default=None, metadata={"insert": False}) dealid: str = field(default=None, metadata={"insert": False, "mtm": "Swap ID"}) + bbg_ticket_id: str = None def __post_init__(self): self.effective_date = previous_twentieth(self.trade_date) @@ -296,9 +313,32 @@ class CDSDeal(BbgDeal, Deal, table_name="cds", insert_ignore=("id", "dealid")): obj["Contractual Supplement"] = "StandardiTraxxEuropeTranche" return obj + @classmethod + def from_bbg_line(cls, line: dict): + values = list(line.values()) + cls._bbg_insert_queue.append(values) + return cls( + fund=_funds[line["Account"]], + folder="*", + portfolio="UNALLOCATED", + security_id=line["Red Code"], + security_desc=line["Security"].removesuffix(" PRC"), + traded_level=Decimal(line["Price (Dec)"]), + notional=line["Quantity"], + fixed_rate=float(line["Coupon"]) * 0.01, + trade_date=datetime.datetime.strptime(line["Trade Dt"], "%m/%d/%Y").date(), + maturity=datetime.datetime.strptime(line["Mat Dt"], "%m/%d/%Y").date(), + currency=line["Curncy"], + protection="Buyer" if line["Side"] == "B" else "Seller", + upfront=line["Principal"], + cp_code=_cdx_cp[line["Brkr"]], + account_code=_fcms[line["Client FCM"]], + bbg_ticket_id=line["bbg_ticket_id"], + ) + @dataclass -class BondDeal(BbgDeal, Deal, table_name="bonds"): +class BondDeal(BbgDeal, Deal, deal_type=DealType.Bond, table_name="bonds"): buysell: bool description: str faceamount: float |
