aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--python/book_bbg.py49
-rw-r--r--python/trade_dataclasses.py48
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