import datetime from serenitas.utils.misc import rename_keys from pyisda.date import previous_twentieth from quantlib.time.api import pydate_from_qldate, UnitedStates, Days, Date from serenitas.analytics.dates import bus_day from .headers import get_headers def get_effective_date(d, swaption_type): if swaption_type == "CD_INDEX_OPTION": return previous_twentieth(d + datetime.timedelta(days=1)) else: cal = UnitedStates() return pydate_from_qldate(cal.advance(Date.from_datetime(d), 2, Days)) _client_name = {"SERCGMAST": "Serenitas", "BOWDST": "HEDGEMARK", "BRINKER": "LMCG"} def build_line(obj, trade_type="bond", fund="SERCGMAST"): obj["Client"] = _client_name[fund] # Bowdst Globeop has a special short name obj["fund"] = "BOS_PAT_BOWDOIN" if fund == "BOWDST" else fund obj["State"] = "Valid" rename_cols = { "fund": "Fund", "action": "Action", "dealid": "Deal Id", "folder": "Folder", "custodian": "Custodian", "cash_account": "Cash Account", "cp_code": "Counterparty", "identifier": "GlopeOp Security Identifier", "cusip": "CUSIP", "isin": "ISIN", "description": "Security Description", "accrued": "Accrued", "price": "Price", "faceamount": "FaceAmount", "trade_date": "Trade Date", "settle_date": "Settlement Date", "effective_date": "EffectiveDate", "maturity": "MaturityDate", "currency": "Currency", "fixed_rate": "FixedRate", "payment_rolldate": "PaymentRollDateConvention", "day_count": "DayCount", "protection": "Protection", "security_id": "UnderlyingSecurityId", "security_desc": "UnderlyingSecurityDescription", "upfront": "UpfrontFee", "upfront_settle_date": "UpfrontFeePayDate", "swap_type": "SwapType", "orig_attach": "AttachmentPoint", "orig_detach": "ExhaustionPoint", "clearing_facility": "Clearing Facility", "isda_definition": "ISDADefinition", "expiration_date": "ExpirationDate", "portfolio": "Portfolio", "settlement_type": "SettlementMode", "principal_payment": "PrincipalPayment", "accrued_payment": "AccruedPayment", "current_face": "CurrentFace", } rename_cols[ "curr_notional" if fund in ("SERCGMAST", "BOWDST") else "notional" ] = "Notional" rename_keys(obj, rename_cols) if trade_type in ("bond", "swaption", "future"): obj["Transaction Indicator"] = "Buy" if obj["buysell"] else "Sell" if trade_type == "bond": obj["Deal Type"] = "MortgageDeal" obj["Portfolio"] = "MORTGAGES" obj["Delivery"] = "S" # zero coupon bond if obj["CUSIP"] != obj["GlopeOp Security Identifier"]: obj["CUSIP"] = None elif trade_type == "swaption": obj["Deal Type"] = "SwaptionDeal" obj["ExerciseType"] = "European" rename_keys( obj, { "Settlement Date": "PremiumSettlementDate", "notional": "Notional", "initial_margin_percentage": "InitialMarginPercentage", }, ) obj["PremiumSettlementAmount"] = ( obj["Price"] * obj["Notional"] * obj.get("factor", 1.0) * 0.01 ) obj["PremiumSettlementCurrency"] = obj["Currency"] obj["RegenerateCashFlow"] = "N" for direction in ["Pay", "Receive"]: obj[direction + "MaturityDate"] = obj["MaturityDate"] obj[direction + "Currency"] = obj["Currency"] obj[direction + "Notional"] = obj["Notional"] obj[direction + "EffectiveDate"] = get_effective_date( obj["ExpirationDate"], obj["SwapType"] ) if obj["SwapType"] == "CD_INDEX_OPTION": for direction in ["Pay", "Receive"]: obj[direction + "Daycount"] = "ACT/360" obj[direction + "Frequency"] = "Quarterly" obj[direction + "PaymentRollConvention"] = "Following" for leg_type in ["Receive", "Pay"]: obj[leg_type + "LegRateType"] = "Fixed" if obj["option_type"] == "PAYER": obj["ReceiveFixedRate"] = 0.0 obj["PayFixedRate"] = obj["FixedRate"] elif obj["option_type"] == "RECEIVER": obj["PayFixedRate"] = 0.0 obj["ReceiveFixedRate"] = obj["FixedRate"] elif obj["SwapType"] == "SWAPTION": for direction in ["Pay", "Receive"]: obj[direction + "PaymentRollConvention"] = "ModifiedFollowing" if obj["option_type"] == "RECEIVER": fixed, floating = "Receive", "Pay" else: fixed, floating = "Pay", "Receive" # fixed leg obj[fixed + "Frequency"] = "Yearly" obj[fixed + "Daycount"] = "ACT/360" obj[fixed + "FixedRate"] = obj["strike"] obj[fixed + "LegRateType"] = "Fixed" obj[fixed + "InterestCalcMethod"] = "Simple Interest" # floating leg obj[floating + "Frequency"] = "Yearly" obj[floating + "Daycount"] = "ACT/360" obj[floating + "LegRateType"] = "Float" obj[floating + "FloatRate"] = "SOFRINDX" obj[floating + "InterestCalcMethod"] = "Simple Interest" else: raise ValueError( "'SwapType' needs to be one of 'CD_INDEX_OPTION' or 'SWAPTION'" ) obj["PremiumCurrency"] = obj["Currency"] if obj["InitialMarginPercentage"]: obj["InitialMarginCurrency"] = obj["Currency"] obj["UnderlyingInstrument"] = obj.pop("UnderlyingSecurityId") if obj["SwapType"] == "CD_INDEX_OPTION": obj["Strike"] = obj.pop("strike") elif trade_type == "cds": freq = {4: "Quarterly", 12: "Monthly"} obj["Deal Type"] = "CreditDefaultSwapDeal" obj["PaymentFrequency"] = freq[obj["frequency"]] obj["InitialMarginPercentage"] = obj.pop("initial_margin_percentage") if obj["InitialMarginPercentage"]: obj["InitialMarginCurrency"] = obj["Currency"] if obj["Clearing Facility"] is None: obj["Clearing Facility"] = "NOT CLEARED" elif trade_type == "future": obj["Deal Type"] = "FutureDeal" rename_keys( obj, { "commission": "Commission", "quantity": "Quantity", "swap_type": "Swap Type", "bbg_ticker": "Bloomberg Ticker", "Currency": "Trade Currency", "exchange": "Exchange", }, ) elif trade_type == "wire": obj["Deal Type"] = "CashFlowDeal" obj["Transaction Type"] = "Transfer" obj["Instrument Type"] = "Cashflow" obj["Settlement Date"] = obj["Trade Date"] strat_portfolio_map = { "IGOPTDEL": "OPTIONS", "COCSH": "OPTIONS", "IGINX": "TRANCHE", "BSPK": "TRANCHE", "TCSH": "TRANCHE", "SER_ITRXCURVE": "SERG__CURVE", "XCURVE": "SERG__CURVE", "M_CSH_CASH": "CASH", "CVECSH": "SERG__CURVE", "SER_ITRXCVCSH": "SERG__CURVE", } obj["Portfolio"] = strat_portfolio_map.get(obj["Folder"]) rename_keys(obj, {"amount": "Amount"}) elif trade_type == "spot": standard_settle = (obj["Trade Date"] + 2 * bus_day).date() if obj["Settlement Date"] > standard_settle: obj["Deal Type"] = "ForwardDeal" fx_rate = "Forward Rate" else: obj["Deal Type"] = "SpotDeal" fx_rate = "Spot Rate" rename_keys( obj, { "commission": "Commission", "commission_currency": "Commission Currency", "sell_currency": "Sell Currency", "sell_amount": "Sell Amount", "buy_currency": "Buy Currency", "buy_amount": "Buy Amount", "spot_rate": fx_rate, }, ) elif trade_type == "fx_swap": obj["Deal Type"] = "FxSwapDeal" obj["Action"] = "NEW" rename_keys( obj, { "near_rate": "Near Side Currency Rate", "near_settle_date": "Near Side Settlement Date", "near_buy_currency": "Near Side Buy Currency", "near_buy_amount": "Near Side Buy Amount", "near_sell_currency": "Near Side Sell Currency", "near_sell_amount": "Near Side Sell Amount", "far_rate": "Far Side Rate", "far_settle_date": "Far Side Settlement Date", "far_buy_currency": "Far Side Buy Currency", "far_buy_amount": "Far Side Buy Amount", "far_sell_currency": "Far Side Sell Currency", "far_sell_amount": "Far Side Sell Amount", }, ) elif trade_type == "repo": obj["Deal Type"] = "RepoDeal" obj["OpenRepo"] = "Y" if obj["open_repo"] else "N" rename_keys( obj, { "weighted_amount": "WeightedAmount", "repo_rate": "RepoRate", "transaction_indicator": "TransactionIndicator", }, ) elif trade_type == "capfloor": obj["Deal Type"] = "CapFloorDeal" obj["PaymentBDC"] = obj["bdc_convention"] obj["AccrualBDC"] = obj["bdc_convention"] obj["MaturityBDC"] = "NONE" obj["TransactionIndicator"] = "Buy" if obj["buysell"] else "Sell" # missing data : 'Adjusted', 'RollConvention', 'Calendar', 'Arrears', 'Collateralized', 'MaturityBDC' rename_keys( obj, { "comments": "Comments", "floating_rate_index_desc": "FloatingRateIndex", "cap_or_floor": "CapOrFloor", "amount": "Notional", "strike": "Strike", "value_date": "ValueDate", "expiration_date": "MaturityDate", "premium_percent": "PremiumPercent", "pricing_type": "PricingType", "payment_frequency": "PaymentFrequency", "fixing_frequency": "FixingFrequency", "day_count_convention": "Basis", "bdc_convention": "PaymentBDC", "payment_mode": "PaymentMode", "payment_at_beginning_or_end": "PaymentAtBeginningOrEnd", "initial_margin_percentage": "InitialMarginPercentage", "intial_margin_currency": "InitialMarginCurrency", "reset_lag": "ResetLag", "swap_type": "SwapType", }, ) return obj