diff options
Diffstat (limited to 'python/ops/trade_dataclasses.py')
| -rw-r--r-- | python/ops/trade_dataclasses.py | 121 |
1 files changed, 31 insertions, 90 deletions
diff --git a/python/ops/trade_dataclasses.py b/python/ops/trade_dataclasses.py index 220611a0..07ac69be 100644 --- a/python/ops/trade_dataclasses.py +++ b/python/ops/trade_dataclasses.py @@ -27,11 +27,12 @@ import warnings logger = logging.getLogger(__name__) -Fund = Literal["SERCGMAST", "BRINKER", "BOWDST"] +Fund = Literal["SERCGMAST", "BRINKER", "BOWDST", "ISOSEL"] Portfolio = Literal[ "OPTIONS", "IR", "MORTGAGES", "CURVE", "TRANCHE", "CLO", "HEDGE_MAC" ] # deprecated IG, HY, STRUCTURED +Status = Literal["Pending", "Submitted", "Acknowledged", "Failed"] _funds = {"BAML": "SERCGMAST", "GS": "BOWDST", "WF": "SERCGMAST"} _fcms = { "Bank of America, N.A.": "BAML", @@ -188,6 +189,14 @@ class DealKind: return SwaptionDeal case "termination": return TerminationDeal + case "irs": + return IRSDeal + case "trs": + return TRSDeal + case "spot": + return SpotDeal + case "fx_swap": + return FxSwapDeal case _: return None @@ -431,100 +440,40 @@ class MTMDeal: class Citco: - _citco_headers = [] - _citco_sftp = SftpClient.from_creds("citco") - _submission_queue = [] - - @classmethod - def citco_upload(cls): - if not cls._citco_queue: # early exit - return - buf = StringIO() - csvwriter = csv.writer(buf) - csvwriter.writerow(cls._citco_headers) - for h in cls._citco_queue: - _citco_to_action = {"R": "UPDATE", "D": "CANCEL", "N": "NEW"} - warnings.warn("we will get rid of overwriting") - h["Fund"] = "ISOSEL" - # Ensure each file is unique - h["Comment"] = f"{datetime.datetime.now():%Y%m%d%H%M%S}" - h["Notes"] = f"{datetime.datetime.now():%Y%m%d%H%M%S}" - identifier = ( - "instrument" if cls.file_tag == "i.innocap_serenitas." else "trade" - ) - unique_id = ( - h["UniqueIdentifier"] - if cls.file_tag == "i.innocap_serenitas." - else h["ClientOrderID"] - ) - cls._submission_queue.append( - [ - unique_id, - _citco_to_action[ - h.get("OrdStatus", "N") - ], # We only update trades, not instruments - identifier, - ] - ) - csvwriter.writerows( - [row.get(h, None) for h in cls._citco_headers] for row in cls._citco_queue - ) - buf = buf.getvalue().encode() - cls._citco_sftp.client.chdir("/incoming") - cls._citco_sftp.put(buf, cls.fname()) - cls.submission_commit() - dest = DAILY_DIR / str(datetime.date.today()) / cls.fname() - dest.write_bytes(buf) - cls._citco_queue.clear() - cls._submission_queue.clear() - - def citco_stage(self, action="NEW"): - self._citco_queue.append(self.to_citco(action)) - - @classmethod - def fname(cls): - return f"{cls.file_tag}{datetime.datetime.now():%Y%m%d%H%M%S}.csv" - - @classmethod - def submission_commit(cls): - sql_str = "INSERT INTO citco_submission_status (serenitas_id, action, identifier_type) VALUES (%s, %s, %s) " - with cls._conn.cursor() as c: - c.executemany(sql_str, cls._submission_queue) - cls._conn.commit() + pass class CitcoProduct(Citco): - _citco_queue: ClassVar[list] = [] - _citco_headers = GIL product_key = () - file_tag = "i.innocap_serenitas." def __init_subclass__(cls, product_key, **kwargs): cls.product_key = product_key def get_productid(self): filter_clause = " AND ".join([f"{k}=%s" for k in self.product_key]) - sql_str = f"SELECT id, dealid, committed FROM {self._table_name} WHERE {filter_clause}" + sql_str = ( + f"SELECT id, deal id, status FROM {self._table_name} WHERE {filter_clause}" + ) with self._conn.cursor() as c: c.execute( sql_str, tuple([getattr(self, k) for k in self.product_key]), ) if results := c.fetchone(): - (self.id, self.dealid, self.committed) = results + (self.id, self.dealid, self.status) = results - def to_citco(self, action): + def to_citco(self): + if not self.id: + self.stage() + self.commit() + self.get_productid() obj = self.serialize("citco") - obj["Birth_date"] = obj["Birth_date"].strftime("%Y%m%d") - obj["Death_date"] = obj["Death_date"].strftime("%Y%m%d") + for k in ["Birth_date", "Death_date"]: + obj[k] = obj[k].strftime("%Y%m%d") return obj class CitcoTrade(Citco): - _citco_queue: ClassVar[list] = [] - _citco_headers = GTL - file_tag = "innocap_serenitas_trades_" - def to_citco(self, action): obj = self.serialize("citco") obj["SettleCurrency"] = "USD" @@ -1612,7 +1561,7 @@ class TrancheProduct( underlying_id_source: str = field( default="RED", metadata={"citco": "UnderlyingIDSource"} ) - committed: bool = field(default=False) + status: Status = field(default="Pending") id: int = field(default=None, metadata={"insert": False}) dealid: str = field( default=None, metadata={"insert": False, "citco": "UniqueIdentifier"} @@ -1649,12 +1598,8 @@ class TrancheProduct( self.currency = "EUR" if index in ("XO", "EU") else "USD" self.get_productid() - def to_citco(self, action): - if not self.id: - self.stage() - self.commit() - self.get_productid() - obj = super().to_citco(action) + def to_citco(self): + obj = super().to_citco() obj["Command"] = "N" obj["Active"] = "Y" obj["CouponRate"] = obj["CouponRate"] / 100 @@ -1723,6 +1668,7 @@ class SwaptionProduct( self.currency = "EUR" if index in ("XO", "EU") else "USD" elif self.instrument_type == "SWPO": self.security_desc = "" + self.underlying_id_source = "USERID" self.get_productid() def to_citco(self): @@ -1731,15 +1677,14 @@ class SwaptionProduct( self.commit() self.get_productid() obj = super().to_citco(action) - if ( - self.underlying_id_source == "USERID" - ): # Implies this is a Interest Rate Swaption + if self.instrument_type == "SWPO": # Implies this is a Interest Rate Swaption irs = IRSProduct( birth_date=self.birth_date, death_date=self.death_date, fixed_rate=self.strike, float_index=self.underlying_security_id, ) + warnings.warn("We're just tacking on the IRS here, it's not very elegant") irs.citco_stage() obj["UnderlyingSecurityId"] = irs.dealid obj["Command"] = "N" @@ -1754,6 +1699,7 @@ _citco_frequency = {"Yearly": 1, "Daily": 9, "Quarterly": 3} _citco_bdc = {"Modified Following": 4} _citco_daycount = {"ACT/360": 2} _citco_ratesource = {"SOFRRATE": 17819} +_to_index = {"SOFRINDX": "SOFRRATE"} _citco_cp_isda = { "MSCSNY": "MS_IS", "GOLDNY": "GS_IS", @@ -1811,12 +1757,7 @@ class IRSProduct( self.security_desc = f"SWAP IRS {self.float_index}-{self.fixed_rate}-{self.birth_date}-{self.death_date}" def to_citco(self): - if not self.id: - self.stage() - self.commit() - self.get_productid() - - obj = super().to_citco(action) + obj = super().to_citco() d = { "S_P_CurrencyCode": self.currency, "S_P_PaymentFreqID": _citco_frequency[self.fixed_payment_freq], @@ -1880,7 +1821,7 @@ class TRSProduct( _citco_trs = {"4J623JAA8": "IBOXHY_TRS"} self.security_desc = f"{_citco_trs[self.underlying_security]}-{self.funding_index}-{self.birth_date}-{self.death_date}" - def to_citco(self): + def to_citco(self, action): if not self.id: self.stage() |
