diff options
| -rw-r--r-- | python/csv_headers/citco.py | 322 | ||||
| -rw-r--r-- | python/headers.py | 4 | ||||
| -rw-r--r-- | python/trade_dataclasses.py | 403 |
3 files changed, 567 insertions, 162 deletions
diff --git a/python/csv_headers/citco.py b/python/csv_headers/citco.py index b836787b..689472a1 100644 --- a/python/csv_headers/citco.py +++ b/python/csv_headers/citco.py @@ -2,13 +2,13 @@ GTL = [ "OrdStatus", "ExecTransType", "ClientOrderID", - "Fill ID", - "ID of Order Or Fill for Action", + "FillID", + "IDofOrderOrFillforAction", "LotNumber", "Symbol", "SecurityType", - "Security Currency", - "Security Description", + "SecurityCurrency", + "SecurityDescription", "BuySellShortCover", "OpenClose", "IDSource", @@ -20,48 +20,48 @@ GTL = [ "CINS", "WhenIssued", "IssueDate", - "Maturity Date", - "Coupon %", + "MaturityDate", + "Coupon%", "ExecutionInterestDays", "AccruedInterest", "FaceValue", "RollableType", - "Repo Currency", - "Day Count Fraction / Repo Calendar", + "RepoCurrency", + "DayCountFraction/RepoCalendar", "RepoLoanAmount", "Trader", "OrderQty", "FillQty", "CumQty", "HairCut", - "Avg Price", + "AvgPrice", "FillPrice", "TradeDate", "TradeTime", "OrigDate", "Unused", "SettlementDate", - "Executing User", + "ExecutingUser", "Comment", "Account", "Fund", "SubFund", "AllocationCode", "StrategyCode", - "Execution Broker", - "Clearing Agent", + "ExecutionBroker", + "ClearingAgent", "ContractSize", "Commission", - "FX Rate", - "FWD FX points", + "FXRate", + "FWDFXpoints", "Fee", "CurrencyTraded", "SettleCurrency", - "FX/BASE rate", - "BASE/FX rate", + "FX/BASErate", + "BASE/FXrate", "StrikePrice", "PutOrCall", - "Derivative Expiry", + "DerivativeExpiry", "SubStrategy", "OrderGroup", "RepoPenalty", @@ -73,54 +73,54 @@ GTL = [ "CurrentFace", "CurrentPrincipalFactor", "AccrualFactor", - "Tax Rate", + "TaxRate", "Expenses", "Fees", "PostCommAndFeesOnInit", - "Implied Commission Flag", - "Transaction Type", - "Master Confrim Type", - "Matrix Term", + "ImpliedCommissionFlag", + "TransactionType", + "MasterConfrimType", + "MatrixTerm", "EMInternalSeqNo.", "ObjectivePrice", "MarketPrice", - "Stop Price", + "StopPrice", "NetConsdieration", - "Fixing Date", - "Delivery Instructions", - "Force Match ID", - "Force Match Type", - "Force Match Notes", - "Commission Rate for Allocation", - "Commission Amount for Fill", - "Expense Amount for Fill", - "Fee Amount for Fill", - "Standard Strategy", - "Strategy Link Name", - "Strategy Group", - "Fill FX Settle Amount", + "FixingDate", + "DeliveryInstructions", + "ForceMatchID", + "ForceMatchType", + "ForceMatchNotes", + "CommissionRateforAllocation", + "CommissionAmountforFill", + "ExpenseAmountforFill", + "FeeAmountforFill", + "StandardStrategy", + "StrategyLinkName", + "StrategyGroup", + "FillFXSettleAmount", "Reserved", "Reserved", - "Deal Attributes", - "Finance Leg", - "Performance Leg", + "DealAttributes", + "FinanceLeg", + "PerformanceLeg", "Attributes", - "Deal Symbol", - "Initial margin type ", - "Initial Margin Amount", - "Initial margin CCY ", - "Confirm Status", + "DealSymbol", + "Initialmargintype", + "InitialMarginAmount", + "InitialmarginCCY", + "ConfirmStatus", "Counterparty", - "Trader Notes", - "Convert Priceto Settle Ccy", - "Bond Coupon Type", - "Generic Fees Enabled", - "Generic Fees Listing", - "Order Level Attributes", + "TraderNotes", + "ConvertPricetoSettleCcy", + "BondCouponType", + "GenericFeesEnabled", + "GenericFeesListing", + "OrderLevelAttributes", "Settling/Sub", - "Confirmation Time", - "Confirmation Means", - "Payment Date", + "ConfirmationTime", + "ConfirmationMeans", + "PaymentDate", "", "", "", @@ -145,23 +145,23 @@ GTL = [ GIL = [ "Command", "Group_Id", - "Unique Identifier", - "Instrument Type", - "Underlying ID Source", - "Underlying Security Id", - "Underlying ISIN", - "Underlying CUSIP", - "Underlying SEDOL", - "Underlying Bloomberg Code", - "Underlying CINS", - "Underlying RIC", - "Underlying CDS", - "Underlying CDSDN", - "Underlying User ID", - "Underlying TID", + "UniqueIdentifier", + "InstrumentType", + "UnderlyingIDSource", + "UnderlyingSecurityId", + "UnderlyingISIN", + "UnderlyingCUSIP", + "UnderlyingSEDOL", + "UnderlyingBloombergCode", + "UnderlyingCINS", + "UnderlyingRIC", + "UnderlyingCDS", + "UnderlyingCDSDN", + "UnderlyingUserID", + "UnderlyingTID", "Symbol", "(BLANK)", - "Birth)date", + "Birth_date", "Death_date", "Active", "(Blank)", @@ -173,46 +173,46 @@ GIL = [ "Country", "SettleCal", "(Blank)", - "Tick Size", + "TickSize", "MarketID", - "Price Base", - "Price Factor", + "PriceBase", + "PriceFactor", "FixRate", "ResetFreq", "(Blank)", "(Blank)", - "1st Cpn Date", - "Last Cpn Date", - "Coupon Rate", - "Cash Flow Freq_Id", + "1stCpnDate", + "LastCpnDate", + "CouponRate", + "CashFlowFreq_Id", "SettleDays", "DayCount_ID", "AccruMethodID", "AccruStartDate", "IssueAmount", "CreditEvent", - "Counter Party", - "Ctpy Abbrev", + "CounterParty", + "CtpyAbbrev", "Tier", - "Ctpy Country", - "Ctpy Country", - "Ctpy moody", - "Bond Class", - "Bond Type", - "Seris Code", + "CtpyCountry", + "CtpyCountry", + "Ctpymoody", + "BondClass", + "BondType", + "SerisCode", "(Blank)", - "Rate Set Date", - "General Direction", - "Principal Exch TypeID", + "RateSetDate", + "GeneralDirection", + "PrincipalExchTypeID", "S_P_PaymentFreqID", - "S_P_Currency Code", + "S_P_CurrencyCode", "S_P_RateIndexID", "S_P_AccrualMethodID", - "S_P_Interest Rate", - "S_P_Payment Calandar", - "S_P_Day Convention", + "S_P_InterestRate", + "S_P_PaymentCalandarID", + "S_P_DayConventionID", "S_P_ResetFreqID", - "S_P_Notional Amt", + "S_P_NotionalAmt", "S_P_ResetCalandarID", "S_P_RateSourceID", "S_P_InitialResetRate", @@ -223,56 +223,56 @@ GIL = [ "S_R_PaymentFreqID", "S_R_CurrencyCode", "S_R_RateIndexID", - "S_R_AccrualMethondID", - "S_R_Interest Rate", + "S_R_AccrualMethodID", + "S_R_InterestRate", "S_R_PaymentCalandarID", "S_R_DayConventionID", "S_R_ResetFreqID", "S_R_NotionalAmount", "S_R_ResetCalandarID", "S_R_RateSource", - "S_R_InitialReset Rate", + "S_R_InitialResetRate", "(Blank)", "(Blank)", "(Blank)", "(Blank)", - "Other Code 1", - "Other Code 1-Value", - "Other Code2", - "Other Code 2-Value", - "Attribute 1", - "Attribute 1-Value", - "Attribute 1-Type", - "Attribute 2", - "Attribute 2-Value", - "Attribute 2-Type", - "Attribute 3", - "Attribute 3-Value", - "Attribute 3-Type", - "Attribute 4", - "Attribute 4-Value", - "Attribute 4-Type", - "Attribute 5", - "Attribute 5-Value", - "Attribute 5-Type", + "OtherCode1", + "OtherCode1-Value", + "OtherCode2", + "OtherCode2-Value", + "Attribute1", + "Attribute1-Value", + "Attribute1-Type", + "Attribute2", + "Attribute2-Value", + "Attribute2-Type", + "Attribute3", + "Attribute3-Value", + "Attribute3-Type", + "Attribute4", + "Attribute4-Value", + "Attribute4-Type", + "Attribute5", + "Attribute5-Value", + "Attribute5-Type", "(Blank)", - "Option Type", - "Strike Month", - "Strike Price", - "Expiration Date", - "Put/Call Flag", - "Contract Size", - "Cash Rebate", - "Barrier 1", - "Barrier 2", + "OptionType", + "StrikeMonth", + "StrikePrice", + "ExpirationDate", + "Put/CallFlag", + "ContractSize", + "CashRebate", + "Barrier1", + "Barrier2", "Notes", "(Blank)", - "Delivery Period Type", - "Delivery Period", - "Delivery Abbrev", - "Days Delay", - "Current Principal Factor", - "Accrual Factor", + "DeliveryPeriodType", + "DeliveryPeriod", + "DeliveryAbbrev", + "DaysDelay", + "CurrentPrincipalFactor", + "AccrualFactor", "(Blank)", "Odd_First_Coupon", "Odd_Last_Coupon", @@ -290,18 +290,18 @@ GIL = [ "Rate_Change_Fre", "Spread_Start_Date", "Rate_Source_Id", - "OTC_Floating Rate_Flag", + "OTC_FloatingRate_Flag", "VAR_Start_Date", - "Future Name", - "Last Trade Date", - "L Code", - "Current Start Date", - "Spot Limit Date", - "First Notice Date", - "Last Notice Date", - "CTD TID", - "CTD Conv. Factor", - "Roll Date", + "FutureName", + "LastTradeDate", + "LCode", + "CurrentStartDate", + "SpotLimitDate", + "FirstNoticeDate", + "LastNoticeDate", + "CTDTID", + "CTDConv.Factor", + "RollDate", "ValueDate1", "EndDate1", "ValueDate2", @@ -312,27 +312,27 @@ GIL = [ "EndDate4", "ValueDate5", "EndDate5", - "Foreign Flag", - "Restricted Flag", - "Par Value", - "Shares Outstanding", + "ForeignFlag", + "RestrictedFlag", + "ParValue", + "SharesOutstanding", "Industry_SIC_ID", - "GICS Level 3 ID", - "Inflation Index Flag", - "Linear Accrual Calc Flag", - "Expiration Time", - "Expiration Time Zone Id", - "Swap Start Date", - "Exp Value Date Time Component", - "Basket Type ID", - "Basket Link Amount 2 ", - "Basket Link Percent 2 ", - "Basket Link TID 3", - "Basket Link Amount 3", - "Basket Link Percent 3", - "Basket Link From Date", - "Basket Link To Date", - "Basket Link Comments ", - "Barrier Option Window 1 ", - "Barrier Option Window 2", + "GICSLevel3ID", + "InflationIndexFlag", + "LinearAccrualCalcFlag", + "ExpirationTime", + "ExpirationTimeZoneId", + "SwapStartDate", + "ExpValueDateTimeComponent", + "BasketTypeID", + "BasketLinkAmount2", + "BasketLinkPercent2", + "BasketLinkTID3", + "BasketLinkAmount3", + "BasketLinkPercent3", + "BasketLinkFromDate", + "BasketLinkToDate", + "BasketLinkComments", + "BarrierOptionWindow1", + "BarrierOptionWindow2", ] diff --git a/python/headers.py b/python/headers.py index 09ede5f4..debe0945 100644 --- a/python/headers.py +++ b/python/headers.py @@ -12,6 +12,10 @@ class DealType(Enum): Fx = "FX" TRS = "TRS" IRS = "IRS" + TrancheProduct = "TRANCHEPRODUCT" + SwaptionProduct = "SWAPTIONPRODUCT" + IRSProduct = "IRSPRODUCT" + TRSProduct = "TRSPRODUCT" HEADERS_PRE = [ diff --git a/python/trade_dataclasses.py b/python/trade_dataclasses.py index 4dcbec71..2e602187 100644 --- a/python/trade_dataclasses.py +++ b/python/trade_dataclasses.py @@ -427,6 +427,41 @@ class MTMDeal: return cls(**{k: v for k, v in kwargs.items() if k in cls._sql_fields}) +from csv_headers.citco import GIL + + +class CitcoDeal: + _citco_queue: ClassVar[list] = [] + _citco_headers = None + _sftp = SftpClient.from_creds("citco") + product_type: str + + def __init_subclass__(cls, deal_type, **kwargs): + super().__init_subclass__(deal_type, **kwargs) + cls._citco_headers = GIL + + @classmethod + def citco_upload(cls): + if not cls._citco_queue: # early exit + return + buf = StringIO() + csvwriter = csv.writer(buf) + csvwriter.writerow(cls._citco_headers) + csvwriter.writerows( + [row.get(h, None) for h in cls._citco_headers] for row in cls._citco_queue + ) + buf = buf.getvalue().encode() + fname = f"i.innocap_serenitas.{datetime.datetime.now():%Y%m%d%H%M%S}.csv" + sftp.client.chdir("incoming") + cls._sftp.put(buf, fname) + dest = DAILY_DIR / str(datetime.date.today()) / fname + dest.write_bytes(buf) + cls._citco_queue.clear() + + def citco_stage(self): + self._citco_queue.append(self.to_citco()) + + @dataclass class CDSDeal( BbgDeal, @@ -1047,7 +1082,6 @@ class TRSDeal( @dataclass class IRSDeal( - # MTMDeal, Deal, deal_type=DealType.IRS, table_name="irs", @@ -1131,3 +1165,370 @@ class IRSDeal( obj["State"] = "Valid" obj.update(d) return obj + + +from enum import IntEnum + + +class TrancheType(IntEnum): + DayCount = 3 + + +@dataclass +class TrancheProduct( + CitcoDeal, + Deal, + deal_type=DealType.TrancheProduct, + table_name="citco_tranche", + insert_ignore=( + "id", + "dealid", + "birth_date", + "death_date", + "security_desc", + "coupon", + "currency", + ), +): + underlying_security_id: str = field(metadata={"citco": "UnderlyingSecurityId"}) + attach: float = field(metadata={"citco": "Attachment_Points"}) + detach: float = field(metadata={"citco": "Detachment_Points"}) + birth_date: datetime.date = field( + init=False, metadata={"insert": False, "citco": "Birth_date"} + ) + death_date: datetime.date = field( + init=False, metadata={"insert": False, "citco": "Death_date"} + ) + coupon: float = field(init=False, metadata={"insert": False, "citco": "CouponRate"}) + security_desc: str = field( + init=False, metadata={"insert": False, "citco": "Sec_Desc"} + ) + currency: str = field(init=False, default=None, metadata={"citco": "LocalCcy"}) + instrument_type: str = field(default="CDS", metadata={"citco": "InstrumentType"}) + underlying_id_source: str = field( + default="RED", metadata={"citco": "UnderlyingIDSource"} + ) + committed: bool = field(default=False) + id: int = field(default=None, metadata={"insert": False}) + dealid: str = field( + default=None, metadata={"insert": False, "citco": "UniqueIdentifier"} + ) + + def get_dealid(self): + sql_str = "SELECT id, dealid, committed from citco_tranche where underlying_security_id = %s and attach = %s and detach = %s" + with self._conn.cursor() as c: + c.execute(sql_str, (self.underlying_security_id, self.attach, self.detach)) + if results := c.fetchone(): + (self.id, self.dealid, self.committed) = results + + def __post_init__(self): + sql_str = "SELECT issue_date, maturity, coupon, index, series FROM index_version LEFT JOIN index_Maturity USING (series, INDEX) WHERE tenor='5yr' AND redindexcode=%s;" + with self._conn.cursor() as c: + c.execute(sql_str, (self.underlying_security_id.removesuffix("_5"),)) + ( + self.birth_date, + self.death_date, + self.coupon, + index, + series, + ) = c.fetchone() + self.get_dealid() + self.security_desc = ( + f"{desc_str(index, series, '5')} {self.attach}-{self.detach}" + ) + self.currency = "EUR" if index in ("XO", "EU") else "USD" + + def to_citco(self): + if not self.id: + self.stage() + self.commit() + self.get_dealid() + obj = self.serialize("citco") + obj["Command"] = "N" + obj["Active"] = "Y" + obj["Birth_date"] = obj["Birth_date"].strftime("%Y%m%d") + obj["Death_date"] = obj["Death_date"].strftime("%Y%m%d") + obj["CouponRate"] = obj["CouponRate"] / 100 + obj["SettleDays"] = 3 + return obj + + +@dataclass +class SwaptionProduct( + CitcoDeal, + Deal, + deal_type=DealType.SwaptionProduct, + table_name="citco_swaption", + insert_ignore=( + "id", + "dealid", + "security_desc", + "currency", + ), +): + underlying_security_id: str = field(metadata={"citco": "UnderlyingSecurityId"}) + security_desc: str = field( + init=False, metadata={"insert": False, "citco": "Sec_Desc"} + ) + currency: str = field( + init=False, default=None, metadata={"citco": "LocalCcy", "insert": False} + ) + instrument_type: str = field(metadata={"citco": "InstrumentType"}) + callput: bool + strike: float = field(metadata={"citco": "StrikePrice"}) + expiration: datetime.date = field(metadata={"citco": "ExpirationDate"}) + underlying_id_source: str = field( + default="RED", metadata={"citco": "UnderlyingIDSource"} + ) + birth_date: datetime.date = field(default=None, metadata={"citco": "Birth_date"}) + death_date: datetime.date = field(default=None, metadata={"citco": "Death_date"}) + + committed: bool = field(default=False) + id: int = field(default=None, metadata={"insert": False}) + dealid: str = field( + default=None, metadata={"insert": False, "citco": "UniqueIdentifier"} + ) + + def get_dealid(self): + sql_str = "SELECT id, dealid, committed from citco_swaption where instrument_type=%s and underlying_security_id =%s and strike =%s and expiration=%s and callput=%s and birth_date=%s and death_date=%s" + with self._conn.cursor() as c: + c.execute( + sql_str, + ( + self.instrument_type, + self.underlying_security_id, + self.strike, + self.expiration, + self.callput, + self.birth_date, + self.death_date, + ), + ) + if results := c.fetchone(): + (self.id, self.dealid, self.committed) = results + + def __post_init__(self): + self.get_dealid() + if self.underlying_id_source == "RED": + sql_str = "SELECT issue_date, maturity, coupon, index, series FROM index_version LEFT JOIN index_Maturity USING (series, INDEX) WHERE tenor='5yr' AND redindexcode=%s;" + with self._conn.cursor() as c: + c.execute(sql_str, (self.underlying_security_id.removesuffix("_5"),)) + ( + self.birth_date, + self.death_date, + self.coupon, + index, + series, + ) = c.fetchone() + self.security_desc = ( + f"{desc_str(index, series, '5')} {self.expiration}-{self.strike}" + ) + self.currency = "EUR" if index in ("XO", "EU") else "USD" + else: + self.security_desc = "" + + def to_citco(self): + if not self.id: + self.stage() + self.commit() + self.get_dealid() + obj = self.serialize("citco") + if self.underlying_id_source == "USERID": + irs = IRSProduct( + birth_date=self.birth_date, + death_date=self.death_date, + fixed_rate=self.strike, + float_index=self.underlying_security_id, + ) + irs.citco_stage() + obj["UnderlyingSecurityId"] = irs.dealid + obj["Command"] = "N" + obj["Active"] = "Y" + obj["Birth_date"] = obj["Birth_date"].strftime("%Y%m%d") + obj["Death_date"] = obj["Death_date"].strftime("%Y%m%d") + obj["ExpirationDate"] = obj["ExpirationDate"].strftime("%Y%m%d") + obj["Put/CallFlag"] = "C" if obj["callput"] else "P" + obj["OptionType"] = "Vanilla European" + return obj + + +_citco_frequency = {"Yearly": 1, "Daily": 9, "Quarterly": 3} +_citco_bdc = {"Modified Following": 4} +_citco_daycount = {"ACT/360": 2} +_citco_ratesource = {"SOFRRATE": 17819} + + +@dataclass +class IRSProduct( + CitcoDeal, + Deal, + deal_type=DealType.IRSProduct, + table_name="citco_irs", + insert_ignore=("id", "dealid", "security_desc"), +): + birth_date: datetime.date = field(metadata={"citco": "Birth_date"}) + death_date: datetime.date = field(metadata={"citco": "Death_date"}) + fixed_rate: float + instrument_type: str = field(default="IRS", metadata={"citco": "InstrumentType"}) + active: str = field(default=True, metadata={"citco": "Active"}) + fixed_daycount: str = field(default="ACT/360") + fixed_payment_freq: str = field(default="Yearly") + fixed_bdc: str = field(default="Modified Following") + float_index: str = field(default="SOFRRATE") + float_daycount: str = field(default="ACT/360") + float_payment_freq: str = field(default="Yearly") + float_bdc: str = field(default="Modified Following") + currency: str = field(default="USD", metadata={"citco": "LocalCcy"}) + float_fixing_freq: str = field(default="Daily") + pay_interest_calc_method: str = field(default="Compound") + committed: bool = field(default=False) + security_desc: str = field( + init=False, metadata={"insert": False, "citco": "Sec_Desc"}, default=None + ) + id: int = field(default=None, metadata={"insert": False}) + dealid: str = field( + default=None, metadata={"insert": False, "citco": "UniqueIdentifier"} + ) + + def get_dealid(self): + sql_str = "SELECT id, dealid, committed from citco_irs where birth_date=%s and death_date=%s and float_index=%s and fixed_rate=%s" + with self._conn.cursor() as c: + c.execute( + sql_str, + ( + self.birth_date, + self.death_date, + self.float_index, + self.fixed_rate, + ), + ) + if results := c.fetchone(): + (self.id, self.dealid, self.committed) = results + self.security_desc = f"SWAP IRS {self.float_index}-{self.fixed_rate}" + + def __post_init__(self): + self.get_dealid() + + def to_citco(self): + if not self.id: + self.stage() + self.commit() + self.get_dealid() + + obj = self.serialize("citco") + d = { + f"S_P_CurrencyCode": self.currency, + f"S_P_PaymentFreqID": _citco_frequency[self.fixed_payment_freq], + f"S_P_RateIndexID": 0, + f"S_P_AccrualMethodID": _citco_daycount[self.fixed_daycount], + f"S_P_InterestRate": self.fixed_rate, + f"S_P_DayConventionID": _citco_bdc[self.fixed_bdc], + f"S_P_ResetFreqID": 0, + f"S_R_CurrencyCode": self.currency, + f"S_R_PaymentFreqID": _citco_frequency[self.float_payment_freq], + f"S_R_RateIndexID": 28, + f"S_R_AccrualMethodID": _citco_daycount[self.float_daycount], + f"S_R_InterestRate": 0, + f"S_R_DayConventionID": _citco_bdc[self.float_bdc], + f"S_R_ResetFreqID": _citco_frequency[self.float_fixing_freq], + f"S_R_RateSource": _citco_ratesource[self.float_index], + } + obj.update(d) + obj["Command"] = "N" + obj["Active"] = "Y" if obj["Active"] else "N" + obj["PrincipalExchTypeID"] = 1 + obj["Birth_date"] = obj["Birth_date"].strftime("%Y%m%d") + obj["Death_date"] = obj["Death_date"].strftime("%Y%m%d") + return obj + + +@dataclass +class TRSProduct( + CitcoDeal, + Deal, + deal_type=DealType.TRSProduct, + table_name="citco_trs", + insert_ignore=("id", "dealid"), +): + birth_date: datetime.date = field(metadata={"citco": "Birth_date"}) + death_date: datetime.date = field(metadata={"citco": "Death_date"}) + underlying_security: str = field(metadata={"citco": "UnderlyingSecurityId"}) + active: str = field(default=True, metadata={"citco": "Active"}) + funding_daycount: str = field(default="ACT/360") + funding_freq: str = field(default="Quarterly") + funding_payment_roll_convention: str = field(default="Modified Following") + asset_daycount: str = field(default="ACT/360") + asset_freq: str = field(default="Quarterly") + asset_payment_roll_convention: str = field(default="Modified Following") + currency: str = field(default="USD", metadata={"citco": "LocalCcy"}) + interest_calc_method: str = field(default="Compound") + compound_avg_frequency: str = field(default="Daily") + fixing_frequency: str = field(default="Daily") + committed: bool = field(default=False) + instrument_type: str = field(default="TRS", metadata={"citco": "InstrumentType"}) + funding_index: str = field(default="SOFRRATE", metadata={}) + security_desc: str = field( + init=False, metadata={"insert": False, "citco": "Sec_Desc"}, default=None + ) + id: int = field(default=None, metadata={"insert": False}) + dealid: str = field( + default=None, metadata={"insert": False, "citco": "UniqueIdentifier"} + ) + + def get_dealid(self): + sql_str = "SELECT id, dealid, committed from citco_trs where birth_date=%s and death_date=%s and funding_index=%s and underlying_security=%s" + with self._conn.cursor() as c: + c.execute( + sql_str, + ( + self.birth_date, + self.death_date, + self.funding_index, + self.underlying_security, + ), + ) + if results := c.fetchone(): + (self.id, self.dealid, self.committed) = results + _citco_trs = {"4J623JAA8": "IBOXHY_TRS"} + self.security_desc = _citco_trs[self.underlying_security] + + def __post_init__(self): + self.get_dealid() + + def to_citco(self): + if not self.id: + + self.stage() + self.commit() + self.get_dealid() + + obj = self.serialize("citco") + d = { + f"S_P_CurrencyCode": self.currency, + f"S_P_PaymentFreqID": _citco_frequency[self.funding_freq], + f"S_P_RateIndexID": 28, + f"S_P_AccrualMethodID": _citco_daycount[self.funding_daycount], + f"S_P_InterestRate": 0, + f"S_P_PaymentCalandarID": 3, + f"S_P_DayConventionID": _citco_bdc[self.funding_payment_roll_convention], + f"S_P_ResetFreqID": _citco_frequency[self.funding_freq], + f"S_P_RateSourceID": _citco_ratesource[self.funding_index], + f"S_R_CurrencyCode": self.currency, + f"S_R_PaymentFreqID": _citco_frequency[self.asset_freq], + f"S_R_RateIndexID": 0, + f"S_R_AccrualMethodID": _citco_daycount[self.asset_daycount], + f"S_R_InterestRate": 0, + f"S_R_PaymentCalandarID": 3, + f"S_R_DayConventionID": _citco_bdc[self.asset_payment_roll_convention], + f"S_R_ResetFreqID": _citco_frequency[self.asset_freq], + f"S_R_RateSourceID": 0, + } + obj.update(d) + obj["Command"] = "N" + obj["Active"] = "Y" if obj["Active"] else "N" + obj["GeneralDirection"] = "F" + obj["PrincipalExchTypeID"] = 3 + obj["Birth_date"] = obj["Birth_date"].strftime("%Y%m%d") + obj["Death_date"] = obj["Death_date"].strftime("%Y%m%d") + obj["UnderlyingIDSource"] = "RED" + return obj |
