def _handle_trade(self, symbol, trade, sessionID): self.logger.info("Trade(s) executed.") # if trade.session.toString() != sessionID.toString(): if trade.session.toString() not in self.sessions: self.logger.debug( f"Trade session {trade.session} and sessionID {sessionID} " f"do not match, skipping trade" ) self.logger.debug(f"Dumping trade \n{trade}") return trade_side = "1" if trade.side == "b" else "2" execution_report = self._create_execution_report( symbol, fix.Side(trade_side), fix.ClOrdID(trade.order_id), price=fix.Price(trade.price), quantity=fix.LastQty(trade.quantity), order_status=fix.OrdStatus_FILLED, exec_type=fix.ExecType_FILL, ) return execution_report
def __get_attributes(self, message): price = fix.LastPx() quantity = fix.LastQty() symbol = fix.Symbol() side = fix.Side() client_order_id = fix.ClOrdID() exec_id = fix.ExecID() order_status = fix.OrdStatus() message.getField(client_order_id) message.getField(side) message.getField(symbol) message.getField(price) message.getField(quantity) message.getField(order_status) message.getField(exec_id) return (symbol, price, quantity, side, client_order_id, exec_id, order_status)
def queryEnterOrder(self): print("\nTradeCaptureReport (AE)\n") trade = fix.Message() trade.getHeader().setField(fix.BeginString(fix.BeginString_FIX44)) trade.getHeader().setField(fix.MsgType(fix.MsgType_TradeCaptureReport)) trade.setField(fix.TradeReportTransType( fix.TradeReportTransType_NEW)) # 487 trade.setField(fix.TradeReportID(self.genTradeReportID())) # 571 trade.setField(fix.TrdSubType(4)) # 829 trade.setField(fix.SecondaryTrdType(2)) # 855 trade.setField(fix.Symbol("MYSYMBOL")) # 55 trade.setField(fix.LastQty(22)) # 32 trade.setField(fix.LastPx(21.12)) # 31 trade.setField(fix.TradeDate( (datetime.now().strftime("%Y%m%d")))) # 75 trade.setField( fix.TransactTime( (datetime.now().strftime("%Y%m%d-%H:%M:%S.%f"))[:-3])) # 60 trade.setField(fix.PreviouslyReported(False)) # 570 group = fix44.TradeCaptureReport().NoSides() group.setField(fix.Side(fix.Side_SELL)) # 54 group.setField(fix.OrderID(self.genOrderID())) # 37 group.setField(fix.NoPartyIDs(1)) # 453 group.setField( fix.PartyIDSource( fix.PartyIDSource_PROPRIETARY_CUSTOM_CODE)) # 447 group.setField(fix.PartyID("CLEARING")) # 448 group.setField(fix.PartyRole(fix.PartyRole_CLEARING_ACCOUNT)) # 452 trade.addGroup(group) group.setField(fix.Side(fix.Side_BUY)) # 54 group.setField(fix.OrderID(self.genOrderID())) # 37 group.setField(fix.NoPartyIDs(1)) # 453 group.setField( fix.PartyIDSource( fix.PartyIDSource_PROPRIETARY_CUSTOM_CODE)) # 447 group.setField(fix.PartyID("CLEARING")) # 448 group.setField(fix.PartyRole(fix.PartyRole_CLEARING_ACCOUNT)) # 452 trade.addGroup(group) fix.Session.sendToTarget(trade, self.sessionID)
def _process_execution_report(self, message): cl_ord_id = self._extract_field(fix.ClOrdID(), message) exec_type = self._extract_field(fix.ExecType(), message) market_order_id = self._extract_optional_field(fix.OrderID(), message) order = self.order_store.find_order(cl_ord_id, market_order_id) # We only update the market order if it's changed self.order_store.store_market_order_id(market_order_id, order.order_id) order.order_id = self.order_store.find_order_id(cl_ord_id) if exec_type == fix.ExecType_NEW: order.status = OrdStatus.NEW self.order_handler.on_new_ack(order) elif exec_type == fix.ExecType_DONE_FOR_DAY: pass elif exec_type == fix.ExecType_CANCELED: order.status = OrdStatus.CANCELED self.order_handler.on_cancel_ack(order) elif exec_type == fix.ExecType_REPLACE: order.status = OrdStatus.REPLACED self.order_handler.on_replace_ack(order) elif exec_type == fix.ExecType_PENDING_CANCEL: self.log.info( 'Received pending cancel for order [order id: {}]'.format( order.order_id)) elif exec_type == fix.ExecType_STOPPED: pass elif exec_type == fix.ExecType_REJECTED: ord_rej_reason = self._extract_field(fix.OrdRejReason(), message) self.log.error('Submission rejected, ({}) {}'.format( OrdRejReason[ord_rej_reason], ord_rej_reason)) order.status = OrdStatus.NEW_REJECT self.order_handler.on_new_rej(order) elif exec_type == fix.ExecType_SUSPENDED: pass elif exec_type == fix.ExecType_PENDING_NEW: self.log.info( 'Received pending new for order [order id: {}]'.format( order.order_id)) elif exec_type == fix.ExecType_CALCULATED: pass elif exec_type == fix.ExecType_EXPIRED: pass elif exec_type == fix.ExecType_RESTATED: pass elif exec_type == fix.ExecType_PENDING_REPLACE: self.log.info( 'Received pending replace for order [order id: {}]'.format( order.order_id)) elif exec_type == fix.ExecType_TRADE: exec_id = self._extract_field(fix.ExecID(), message) transact_time = self._extract_date_field(fix.TransactTime(), message) remaining_qty = self._extract_field(fix.LeavesQty(), message) executed_qty = self._extract_field(fix.CumQty(), message) last_qty = self._extract_field(fix.LastQty(), message) last_px = self._extract_field(fix.LastPx(), message) order.executed_qty = executed_qty execution = Execution(order.order_id) execution.exec_id = exec_id execution.transact_time = transact_time execution.last_price = last_px execution.last_qty = last_qty if remaining_qty == 0: order.status = OrdStatus.FULLY_FILLED else: order.status = OrdStatus.PARTIALLY_FILLED self.order_store.store_exec_id(exec_id, execution) self.order_handler.on_execution(order, execution) elif exec_type == fix.ExecType_TRADE_CORRECT: pass elif exec_type == fix.ExecType_TRADE_CANCEL: pass elif exec_type == fix.ExecType_ORDER_STATUS: pass else: self.log.error('Unknown execType: {}'.format(exec_type))