def cancel(self, message, sessionID): symbol = fix.Symbol() side = fix.Side() orderQty = fix.OrderQty() clOrdID = fix.ClOrdID() org = fix.OrigClOrdID() message.getField(symbol) message.getField(side) message.getField(orderQty) message.getField(clOrdID) message.getField(org) log.info("cancel:\nsymbol:{},side:{},orderQty:{},clOrdID:{},org:{} -----"\ .format(symbol, side, orderQty, clOrdID, org)) cancel = fix44.OrderCancelReject() cancel.setField(clOrdID) cancel.setField(fix.OrderID(self.genOrderID())) cancel.setField(fix.OrdStatus(fix.OrdStatus_NEW)) cancel.setField(fix.OrigClOrdID(org.getValue())) cancel.setField(fix.Text('order completed')) cancel.setField(fix.TransactTime()) cancel.setField(fix.CxlRejReason(fix.CxlRejReason_BROKER)) cancel.setField( fix.CxlRejResponseTo(fix.CxlRejResponseTo_ORDER_CANCEL_REQUEST)) fix.Session.sendToTarget(cancel, sessionID)
def sendCancelAck(self, orderID): message = self.startFIXString(orderID) message.setField(quickfix.OrderQty(self.orders[orderID]['leaves'])) message.setField(quickfix.ExecType(quickfix.ExecType_CANCELED)) if 'cxlClOrdID' in self.orders[orderID]: message.setField(quickfix.ClOrdID(self.orders[orderID]['cxlClOrdID'])) if 'origClOrdID' in self.orders[orderID]: message.setField(quickfix.OrigClOrdID(self.orders[orderID]['origClOrdID'])) else: message.setField(quickfix.OrigClOrdID(self.orders[orderID]['clOrdID'])) quickfix.Session.sendToTarget(message, self.orders[orderID]['session']) self.orders[orderID]['state'] = 'Canceled'
def getOrderCancelReject(self, message): beginString = fix.BeginString() message.getHeader().getField(beginString) clOrdID = fix.ClOrdID() orderID = fix.OrderID() origClOrdID = fix.OrigClOrdID() message.getField(clOrdID) message.getField(orderID) message.getField(origClOrdID) orderCancelReject = fix.Message() orderCancelReject.getHeader().setField(beginString) orderCancelReject.getHeader().setField( fix.MsgType(fix.MsgType_OrderCancelReject)) orderCancelReject.setField(clOrdID) orderCancelReject.setField(orderID) orderCancelReject.setField(origClOrdID) orderCancelReject.setField(fix.OrdStatus( fix.OrdStatus_FILLED)) #39 = 2 FILLED orderCancelReject.setField( fix.CxlRejReason(0)) #102=0 TOO_LATE_TO_CANCEL orderCancelReject.setField( fix.CxlRejResponseTo(1)) #434=1 ORDER_CANCEL_REQUEST return orderCancelReject
def cancel_order(self, execution_report): message = quickfix44.OrderCancelRequest() orig_cl_ord_id = quickfix.OrigClOrdID() order_id = quickfix.OrderID() symbol_field = quickfix.Symbol() security_exchange_field = quickfix.SecurityExchange() execution_report.getField(symbol_field) execution_report.getField(security_exchange_field) execution_report.getField(order_id) orig_cl_ord_id.setValue(order_id.getValue()) message.setField(symbol_field) message.setField(security_exchange_field) message.setField(orig_cl_ord_id) message.setField(quickfix.ClOrdID(self.genExecID())) side = quickfix.Side() execution_report.getField(side) message.setField(side) trstime = quickfix.TransactTime() trstime.setString( datetime.utcnow().strftime("%Y%m%d-%H:%M:%S.%f")[:-3]) message.setField(trstime) quickfix.Session.sendToTarget(message, self.sessionID)
def sendReplacePending(self, orderID): origClientOrderID = self.orders[orderID]['origClOrdID'] message = self.startFIXString(orderID) message.setField(quickfix.OrderQty(self.orders[orderID]['quantity'])) message.setField(quickfix.ExecType(quickfix.ExecType_PENDING_REPLACE)) message.setField(quickfix.OrigClOrdID(origClientOrderID)) quickfix.Session.sendToTarget(message, self.orders[orderID]['session'])
def _create_execution_report( self, symbol, side, client_order_id, price=None, quantity=None, order_status=fix.OrdStatus_NEW, exec_trans_type=fix.ExecTransType_NEW, exec_type=fix.ExecType_NEW, text=None, reject_reason=None, orig_client_order_id=None, ): # defaults execution_report = Message() execution_report.getHeader().setField( fix.MsgType(fix.MsgType_ExecutionReport)) execution_report.setField( fix.OrderID(self.generate_order_id(symbol.getValue()))) execution_report.setField( fix.ExecID(self.generate_execution_id(symbol.getValue()))) execution_report.setField(fix.OrdStatus(order_status)) execution_report.setField(symbol) execution_report.setField(side) execution_report.setField(client_order_id) execution_report.setField(fix.ExecTransType(exec_trans_type)) execution_report.setField(fix.ExecType(exec_type)) execution_report.setField(fix.LeavesQty(0)) if price: execution_report.setField(fix.AvgPx(price.getValue())) execution_report.setField(fix.LastPx(price.getValue())) if quantity: execution_report.setField(fix.CumQty(quantity.getValue())) execution_report.setField(fix.LastShares(quantity.getValue())) execution_report.setField(quantity) if orig_client_order_id: execution_report.setField( fix.OrigClOrdID(orig_client_order_id.getValue())) if text: execution_report.setField(fix.Text(text)) if exec_type == fix.ExecType_REJECTED: execution_report.setField(fix.OrdRejReason(reject_reason)) self.logger.debug( f"Created execution report {execution_report.__str__()}") return execution_report
def sendReplaceAck(self, orderID): origOrdID = self.orders[orderID]['origOrdID'] origClientOrderID = self.orders[orderID]['origClOrdID'] message = self.startFIXString(orderID) message.setField(quickfix.OrderQty(self.orders[orderID]['quantity'])) message.setField(quickfix.ExecType(quickfix.ExecType_REPLACED)) message.setField(quickfix.ExecTransType(quickfix.ExecTransType_NEW)) message.setField(quickfix.OrigClOrdID(origClientOrderID)) quickfix.Session.sendToTarget(message, self.orders[orderID]['session']) self.orders[orderID]['state'] = 'New' self.orders[origOrdID]['state'] = 'Replaced'
def fromApp(self, message, sessionID): beginString = fix.BeginString() msgType = fix.MsgType() message.getHeader().getField( beginString ) message.getHeader().getField( msgType ) if msgType.getValue() == 'F': print 'Cancel Request' symbol = fix.Symbol() side = fix.Side() clOrdID = fix.ClOrdID() origClOrdID = fix.OrigClOrdID() orderQty = fix.OrderQty() message.getField( orderQty ) message.getField( clOrdID ) message.getField( origClOrdID ) message.getField( symbol ) message.getField( side ) executionReport = fix.Message() executionReport.getHeader().setField( beginString ) executionReport.getHeader().setField( fix.MsgType(fix.MsgType_ExecutionReport) ) executionReport.setField( symbol ) executionReport.setField( side ) executionReport.setField( clOrdID ) executionReport.setField( origClOrdID ) executionReport.setField( fix.ExecID(self.genExecID()) ) executionReport.setField( fix.OrderID(self.genOrderID()) ) executionReport.setField( fix.AvgPx(0)) executionReport.setField( fix.LastShares(0)) executionReport.setField( fix.CumQty(0)) if beginString.getValue() == fix.BeginString_FIX40 or beginString.getValue() == fix.BeginString_FIX41 or beginString.getValue() == fix.BeginString_FIX42: executionReport.setField( fix.ExecTransType(fix.ExecTransType_CANCEL) ) executionReport.setField( fix.OrdStatus(fix.OrdStatus_CANCELED) ) if beginString.getValue() >= fix.BeginString_FIX41: executionReport.setField( fix.ExecType(fix.ExecType_CANCELED) ) executionReport.setField( fix.LeavesQty(0) ) else: executionReport.setField( fix.ExecType(fix.ExecType_CANCELED) ) executionReport.setField( fix.LeavesQty(0) ) try: print executionReport fix.Session.sendToTarget( executionReport, sessionID ) except SessionNotFound, e: return
def cancel_child_order(self, message: fix.Message): """""" cl_ord_id = get_field_value(message, fix.OrigClOrdID()) vt_orderid = self.genus_vt_map.get(cl_ord_id, "") if vt_orderid: child_order = self.child_orders[vt_orderid] if child_order.ord_status not in {"2", "8", "4"}: self.client.cancel_order(vt_orderid) return # Reject cancel request self.exec_id += 1 message = new_message(fix.MsgType_OrderCancelReject) message.setField(fix.ClOrdID(cl_ord_id)) message.setField(fix.OrigClOrdID(cl_ord_id)) message.setField(fix.OrdStatus("8")) message.setField(fix.ExecID(str(self.exec_id))) message.setField(434, "1") fix.Session.sendToTarget(message, self.session_id)
def sendOrderCancelRequest(self): message = fix.Message() header = message.getHeader() header.setField(fix.BeginString("FIX.4.2")) header.setField(fix.SenderCompID("CLIENT1")) header.setField(fix.TargetCompID("EXECUTOR")) header.setField(fix.MsgType("D")) message.setField(fix.OrigClOrdID("123")) message.setField(fix.ClOrdID("321")) message.setField(fix.Symbol("LNUX")) message.setField(fix.Side(fix.Side_BUY)) message.setField(fix.Text("Cancel My Order!")) fix.Session.sendToTarget(message, self.sessionID)
def delete_order(sender_comp_id, target_comp_id, orig_client_order_id): symbol = ORDERS[orig_client_order_id][0].getValue() side = ORDERS[orig_client_order_id][3].getValue() message = fix44.OrderCancelRequest() header = message.getHeader() header.setField(fix.SenderCompID(sender_comp_id)) header.setField(fix.TargetCompID(target_comp_id)) ord_id = get_order_id(sender_comp_id, symbol) message.setField(fix.OrigClOrdID(orig_client_order_id)) message.setField(fix.ClOrdID(ord_id)) message.setField(fix.Symbol(symbol)) message.setField(fix.Side(side)) message.setField(fix.TransactTime()) message.setField(fix.Text(f"Delete {orig_client_order_id}")) return message
def generate_message_fields(self, message_type): message_fields = { 'client_orderID': fix.ClOrdID(), 'symbol': fix.Symbol(), 'side': fix.Side(), 'quantity': fix.OrderQty(), } if message_type in ['new', 'replace']: extra_message_fields = { 'type': fix.OrdType(), 'price': fix.Price(), 'handlInst': fix.HandlInst(), } message_fields.update(extra_message_fields) if message_type == 'replace': message_fields['original_orderID'] = fix.OrigClOrdID() return message_fields
def order_cancel_request(self,account,symbol,side,quantity): print("Creating order_cancel_request message... ") cancel_request_message = fix.Message() cancel_request_message.getHeader().setField(fix.BeginString(fix.BeginString_FIX42)) # cancel_request_message.getHeader().setField(fix.MsgType('F')) #39=D cancel_request_message.getHeader().setField(fix.SendingTime(1)) cancel_request_message.setField(fix.Account(str(account))) #1 cancel_request_message.setField(fix.ClOrdID(str('order_cancel_request'+self.genOrderID()))) #11 cancel_request_message.setField(fix.OrigClOrdID(str(self.orders[0]))) #41 cancel_request_message.setField(fix.Symbol(str(symbol))) #55 cancel_request_message.setField(fix.Side(str(side))) #54 cancel_request_message.setField(fix.OrderQty(quantity)) #38 print('sending order_cancel_request message...') print(f'order_cancel_request message: {cancel_request_message.toString()}') fix.Session.sendToTarget(cancel_request_message, self.sessionID) print('order_cancel_request message sent!')
def cancel_parent_order(self, parent_orderid: str): """""" algo_setting = self.algo_settings.get(parent_orderid, None) if not algo_setting: print(f"{parent_orderid} algo setting not found.") return message = new_message(fix.MsgType_OrderCancelRequest) self.parent_orderid += 1 cancel_orderid = f"Cancel_{self.parent_orderid}" message.setField(fix.ClOrdID(cancel_orderid)) message.setField(fix.OrigClOrdID(parent_orderid)) message.setField(fix.Symbol(algo_setting["symbol"])) message.setField(fix.Side(algo_setting["side"])) message.setField(847, algo_setting["algo_type"]) message.setField(fix.Text("vnpy")) fix.Session.sendToTarget(message, self.session_id)
def cancel(self, trade): orderId = self.SocketInitiator.application.genOrderID() account = self.SocketInitiator.application.Settings.get().getString( 'Account') cancel = fix44.OrderCancelRequest() cancel.setField(fix.Account(account)) cancel.setField(fix.ClOrdID(orderId)) cancel.setField(fix.OrigClOrdID(trade.OrderId)) cancel.setField(trade.CFICode) cancel.setField(fix.TransactTime()) cancel.setField(fix.OrderQty(trade.Quantity)) cancel.setField( fix.Side(fix.Side_BUY if trade.OrderSide == OrderSide.Buy else fix.Side_SELL)) cancel.setField(fix.Symbol(trade.Symbol)) cancel.setField(fix.MaturityMonthYear(trade.Maturity)) self.SocketInitiator.application.send(cancel)
def handle_execution_report(self, message): order_id = TradingClass.FIXHandlerUtils.get_field_value(fix.OrderID(), message) cl_ord_id = TradingClass.FIXHandlerUtils.get_field_value(fix.ClOrdID(), message) orig_cl_ord_id = TradingClass.FIXHandlerUtils.get_field_value(fix.OrigClOrdID(), message) exec_id = TradingClass.FIXHandlerUtils.get_field_value(fix.ExecID(), message) exec_trans_type = TradingClass.FIXHandlerUtils.get_field_value(fix.ExecTransType(), message) exec_type = TradingClass.FIXHandlerUtils.get_field_value(fix.ExecType(), message) ord_status = TradingClass.FIXHandlerUtils.get_field_value(fix.OrdStatus(), message) symbol = TradingClass.FIXHandlerUtils.get_field_value(fix.Symbol(), message) side = TradingClass.FIXHandlerUtils.get_field_value(fix.Side(), message) leaves_qty = TradingClass.FIXHandlerUtils.get_field_value(fix.LeavesQty(), message) price = TradingClass.FIXHandlerUtils.get_field_value(fix.Price(), message) cum_qty = TradingClass.FIXHandlerUtils.get_field_value(fix.CumQty(), message) avg_px = TradingClass.FIXHandlerUtils.get_field_value(fix.AvgPx(), message) order_execution = TradingClass.ExecutionReport(order_id, cl_ord_id, exec_id, exec_trans_type, exec_type, ord_status, symbol, side, leaves_qty, cum_qty, avg_px, price, orig_cl_ord_id) self.client_logic.process_order_execution_respond(order_execution) return
def on_parent_order(self, message: fix.Message): """""" parent_orderid = get_field_value(message, fix.ClOrdID()) # Get parent orderid of cancel request if parent_orderid.startswith("Cancel"): parent_orderid = get_field_value(message, fix.OrigClOrdID()) # If this parent order is from previous session if parent_orderid not in self.algo_settings: # Cancel it to avoid future update self.cancel_parent_order(parent_orderid) return tradeid = get_field_value(message, fix.ExecID()) status = get_field_value(message, fix.OrdStatus()) side = get_field_value(message, fix.Side()) genus_symbol = get_field_value(message, fix.Symbol()) order_traded = get_field_value(message, fix.CumQty()) text = get_field_value(message, fix.Text()) algo_type = get_field_value(message, fix.StringField(847)) variables = {"推送编号": tradeid, "已成交": order_traded, "算法信息": text} self.algo_settings[parent_orderid] = { "symbol": genus_symbol, "side": side, "algo_type": algo_type } # Add algo active status if status in {"0", "1", "5", "6", "A", "D", "E"}: variables["active"] = True else: variables["active"] = False if status == "C": self.client.write_log("执行时间已结束,停止算法", parent_orderid) self.client.put_variables_event(parent_orderid, variables)
def on_replace_request(self, message): print('replace!') message_fields = { 'client_orderID': fix.ClOrdID(), 'original_clientID': fix.OrigClOrdID(), 'symbol': fix.Symbol(), 'type': fix.OrdType(), 'side': fix.Side(), 'quantity': fix.OrderQty(), 'price': fix.Price(), 'handlInst': fix.HandlInst(), } message_details = {} for k, v in message_fields.items(): message_details[k] = self.get_field_value(message, v) orderID = self.gen_orderID() self.orders[orderID] = message_details # testing self.test_replies(orderID, fix.OrdStatus_PENDING_REPLACE, fix.ExecType_REPLACE, message_details)
def order_cancel_replace(self,account,symbol,side,quantity,order_type,price): print("Creating order_cancel_replace message... ") cancel_replace_message = fix.Message() cancel_replace_message.getHeader().setField(fix.BeginString(fix.BeginString_FIX42)) # cancel_replace_message.getHeader().setField(fix.MsgType('G')) #39=D cancel_replace_message.getHeader().setField(fix.SendingTime(1)) cancel_replace_message.setField(fix.Account(str(account))) #1 cancel_replace_message.setField(fix.HandlInst(fix.HandlInst_AUTOMATED_EXECUTION_ORDER_PUBLIC_BROKER_INTERVENTION_OK)) #21=3 (Manual order), 21=2 automated execution only supported value cancel_replace_message.setField(fix.ClOrdID(str('order_cancel_replace'+self.genOrderID()))) #11 cancel_replace_message.setField(fix.OrigClOrdID(str(self.orders[0]))) #41 cancel_replace_message.setField(fix.Symbol(str(symbol))) #55 cancel_replace_message.setField(fix.Side(str(side))) #54 cancel_replace_message.setField(fix.OrderQty(quantity)) #38 cancel_replace_message.setField(fix.OrdType(str(order_type))) #40 cancel_replace_message.setField(fix.Price(price)) #44 print('sending order_cancel_replace message...') print(f'order_cancel_replace message: {cancel_replace_message.toString()}') fix.Session.sendToTarget(cancel_replace_message, self.sessionID) print('order_cancel_replace message sent!')
def on_cancel_request(self, message): print('Cancel!') message_fields = { 'client_orderID': fix.ClOrdID(), 'original_clientID': fix.OrigClOrdID(), 'symbol': fix.Symbol(), 'side': fix.Side(), 'quantity': fix.OrderQty(), } message_details = {} for k, v in message_fields.items(): message_details[k] = self.get_field_value(message, v) orderID = self.gen_orderID() self.orders[orderID] = message_details # testing self.test_replies(orderID, fix.OrdStatus_CANCELED, fix.ExecType_CANCELED, message_details, reject=True)
def cancel_order(self): message = fix.Message() header = message.getHeader() header.setField(fix.BeginString(fix.BeginString_FIX42)) header.setField(fix.MsgType(fix.MsgType_OrderCancelRequest)) #35=F originalOrderId = str(int(self.genOrderID()) - 1) message.setField(fix.OrigClOrdID(originalOrderId)) message.setField(fix.ClOrdID(str(int(originalOrderId) + 1))) #11=Unique order id message.setField(fix.OrderID("375")) message.setField(fix.Symbol("ABCD")) #55=ABCD message.setField(fix.Side(fix.Side_BUY)) #54=1 Buy message.setField( fix.StringField( 60, (datetime.utcnow().strftime("%Y%m%d-%H:%M:%S.%f"))[:-3]) ) #60 TransactTime, not supported in python, so use tag number message.setField(fix.Text("Cancel my Order")) #58 text print(message.toString()) try: fix.Session.sendToTarget(message, self.sessionID) except (fix.ConfigError, fix.RuntimeError) as e: print(e)
def send_order_cancel_request(self, order_cancel_request): """ Args: order_cancel_request (TradingClass.OrderCancelRequest) Returns: None """ # Create Fix Message for Order Cancel Request message = fix.Message() header = message.getHeader() header.setField(fix.MsgType(fix.MsgType_OrderCancelRequest)) transact_time_fix = fix.TransactTime() transact_time_fix.setString(order_cancel_request.transact_time.__str__()) message.setField(fix.OrigClOrdID(order_cancel_request.orig_cl_ord_id)) message.setField(fix.ClOrdID(order_cancel_request.cl_ord_id)) message.setField(fix.Symbol(order_cancel_request.symbol)) message.setField(fix.Side(order_cancel_request.side)) message.setField(transact_time_fix) message.setField(fix.OrderQty(order_cancel_request.order_qty)) # Send Fix Message to Server fix.Session.sendToTarget(message, self.fix_application.sessionID)
def replace_order(sender_comp_id, target_comp_id, quantity, price, orig_client_order_id): symbol = ORDERS[orig_client_order_id][0].getValue() side = ORDERS[orig_client_order_id][3].getValue() message = fix42.OrderCancelReplaceRequest() header = message.getHeader() header.setField(fix.SenderCompID(sender_comp_id)) header.setField(fix.TargetCompID(target_comp_id)) ord_id = get_order_id(sender_comp_id, symbol) message.setField(fix.OrigClOrdID(orig_client_order_id)) message.setField(fix.ClOrdID(ord_id)) message.setField(fix.Symbol(symbol)) message.setField(fix.Side(side)) message.setField(fix.Price(float(price))) message.setField(fix.OrdType(fix.OrdType_LIMIT)) message.setField(fix.HandlInst(fix.HandlInst_MANUAL_ORDER_BEST_EXECUTION)) message.setField(fix.TransactTime()) message.setField(fix.TransactTime()) message.setField(fix.OrderQty(float(quantity))) message.setField(fix.Text(f"{side} {symbol} {quantity}@{price}")) return message
def __unpackMessage(self, message): msgType = fix.MsgType() message.getHeader().getField(msgType) if msgType.getValue() == fix.MsgType_RequestForPositionsAck: account = fix.Account() message.getField(account) posId = fix.PosReqID() message.getField(posId) self.Notifier.notifyMsgHandlers( Notify.Account, Account=account.getValue(), PosReqID=posId.getValue(), Symbol=None, Maturity=None, NoPositions=0, LongQty=0, ShortQty=0, PosAmt=0, SettlPrice=0, NoPosAmt=0, ClearingBusinessDate=None, AccountInquiry=AccountInquiry.RequestForPositions) elif msgType.getValue() == fix.MsgType_PositionReport: account = fix.Account() message.getField(account) posId = fix.PosReqID() message.getField(posId) symbol = fix.Symbol() message.getField(symbol) maturity = fix.MaturityMonthYear() message.getField(maturity) noPositions = fix.NoPositions() message.getField(noPositions) longQty = fix.LongQty() message.getField(longQty) shortQty = fix.ShortQty() message.getField(shortQty) posAmt = fix.PosAmt() message.getField(posAmt) cBusDate = fix.ClearingBusinessDate() message.getField(cBusDate) settlePrice = fix.SettlPrice() message.getField(settlePrice) noPosAmt = fix.NoPosAmt() message.getField(noPosAmt) self.Notifier.notifyMsgHandlers( Notify.Account, Account=account.getValue(), PosReqID=posId.getValue(), Symbol=symbol.getValue(), Maturity=maturity.getValue(), NoPositions=noPositions.getValue(), LongQty=longQty.getValue(), ShortQty=shortQty.getValue(), PosAmt=posAmt.getValue(), SettlPrice=settlePrice.getValue(), NoPosAmt=noPosAmt.getValue(), ClearingBusinessDate=cBusDate.getValue(), AccountInquiry=AccountInquiry.RequestForPositions) elif msgType.getValue() == fix.MsgType_CollateralReport: account = fix.Account() message.getField(account) ccy = fix.Currency() message.getField(ccy) csh = fix.CashOutstanding() message.getField(csh) colId = fix.CollInquiryID() message.getField(colId) self.Notifier.notifyMsgHandlers( Notify.Account, Account=account.getValue(), Currency=ccy.getValue(), Balance=csh.getValue(), CollInquiryID=colId.getValue(), AccountInquiry=AccountInquiry.CollateralInquiry) elif msgType.getValue() == fix.MsgType_OrderCancelReject: cId = fix.ClOrdID() message.getField(cId) origClOrdID = fix.OrigClOrdID() message.getField(origClOrdID) self.Notifier.notifyMsgHandlers(Notify.Order, ClientOrderId=cId.getValue(), Symbol=None, AvgPx=None, Quantity=None, Side=None, Status=OrderStatus.CancelRejected, OrigClOrdID=origClOrdID.getValue(), Sender=self.FixClientRef) elif msgType.getValue() == fix.MsgType_ExecutionReport: cId = fix.ClOrdID() message.getField(cId) fixStatus = fix.OrdStatus() message.getField(fixStatus) price = fix.AvgPx() message.getField(price) qty = fix.OrderQty() message.getField(qty) side = fix.Side() message.getField(side) symbol = fix.Symbol() message.getField(symbol) orderSide = None origOrderId = None if side.getValue() == fix.Side_BUY: orderSide = OrderSide.Buy elif side.getValue() == fix.Side_SELL: orderSide = OrderSide.Sell status = None if fixStatus.getValue() == fix.OrdStatus_NEW: status = OrderStatus.New elif fixStatus.getValue() == fix.OrdStatus_CANCELED: status = OrderStatus.Cancelled origClOrdID = fix.OrigClOrdID() message.getField(origClOrdID) origOrderId = origClOrdID.getValue() elif fixStatus.getValue() == fix.OrdStatus_FILLED: status = OrderStatus.Filled elif fixStatus.getValue() == fix.OrdStatus_REJECTED: status = OrderStatus.Rejected if status is not None: self.Notifier.notifyMsgHandlers(Notify.Order, ClientOrderId=cId.getValue(), Symbol=symbol.getValue(), AvgPx=price.getValue(), Quantity=qty.getValue(), Side=orderSide, Status=status, OrigClOrdID=origOrderId, Sender=self.FixClientRef)
def fromApp(self, message, session): clientOrderID = self.getValue(message, quickfix.ClOrdID()) targetCompID = session.getTargetCompID().getValue() details = {'session' : session, 'clOrdID' : clientOrderID, 'target' : targetCompID, 'symbol' : self.getValue(message, quickfix.Symbol()), 'side' : self.getValue(message, quickfix.Side()), 'sideStr' : self.getSide(self.getValue(message, quickfix.Side())), 'quantity' : self.getValue(message, quickfix.OrderQty()), 'leaves' : self.getValue(message, quickfix.OrderQty())} if self.getHeaderValue(message, quickfix.MsgType()) == quickfix.MsgType_NewOrderSingle: ## Received new order from client orderID = self.getNextOrderID() print "\nNewOrder {} received\n--> ".format(orderID), details['ordType'] = self.getValue(message, quickfix.OrdType()) details['state'] = 'PendingAck' if (self.getValue(message, quickfix.OrdType()) == quickfix.OrdType_LIMIT or self.getValue(message, quickfix.OrdType()) == quickfix.OrdType_LIMIT_ON_CLOSE): # Limit orders will have a price, Market order will not. details['price'] = self.getValue(message, quickfix.Price()) self.orders[orderID] = details self.sessions[targetCompID][clientOrderID] = orderID if self.getHeaderValue(message, quickfix.MsgType()) == quickfix.MsgType_OrderCancelRequest: origClientOrderID = self.getValue(message, quickfix.OrigClOrdID()) details['origClOrdID'] = origClientOrderID details['cxlClOrdID'] = clientOrderID if origClientOrderID not in self.sessions[targetCompID]: # A cancel request has come in for an order we don't have in the book # So let's create that order in the book based on what we know orderID = self.getNextOrderID() self.orders[orderID] = details self.sessions[targetCompID][origClientOrderID] = orderID else: ## We have the order in the book orderID = self.sessions[targetCompID][origClientOrderID] self.orders[orderID]['cxlClOrdID'] = clientOrderID self.orders[orderID]['state'] = 'PendingCancel' print "\nCancelRequest for OrderID {} received\n--> ".format(orderID), if self.getHeaderValue(message, quickfix.MsgType()) == quickfix.MsgType_OrderCancelReplaceRequest: origClientOrderID = self.getValue(message, quickfix.OrigClOrdID()) if origClientOrderID not in self.sessions[targetCompID]: ## A replace request has come in for an order we don't have in the book orderID = self.getNextOrderID() self.orders[orderID] = details self.sessions[targetCompID][origClientOrderID] = orderID else: ## We have the original order in the book orderID = self.sessions[targetCompID][origClientOrderID] self.orders[orderID]['rplClOrdID'] = clientOrderID self.orders[orderID]['state'] = 'PendingReplace' newOrderID = self.getNextOrderID() self.orders[newOrderID] = details self.orders[newOrderID]['origClOrdID'] = origClientOrderID self.orders[newOrderID]['origOrdID'] = orderID self.orders[newOrderID]['state'] = 'PendingNew' print "OrderID {} to replace OrderID {} received\n--> ".format(newOrderID, orderID),
def order_replace(self, message, sessionID): ( symbol, price, quantity, side, order_type, client_order_id, ) = self.__get_attributes(message) orig_client_order_id = fix.OrigClOrdID() message.getField(orig_client_order_id) execution_report = None market = symbol.getValue() if market not in MARKETS: execution_report = self._create_execution_report( symbol, side, client_order_id, price=price, quantity=quantity, text=f"Symbol {symbol.getValue()} not found.", exec_type=fix.ExecType_REJECTED, reject_reason=fix.OrdRejReason_UNKNOWN_SYMBOL, ) return [(sessionID, execution_report)] self.logger.debug(CLIENT_ORDER_IDs) if (sessionID.toString() not in CLIENT_ORDER_IDs) or ( orig_client_order_id.getValue() not in CLIENT_ORDER_IDs[sessionID.toString()] ): execution_report = self._create_execution_report( symbol, side, client_order_id, price=price, quantity=quantity, text=f"Client order ID {client_order_id.getValue()} not found.", exec_type=fix.ExecType_REJECTED, reject_reason=fix.OrdRejReason_UNKNOWN_ORDER, ) return [(sessionID, execution_report)] if sessionID.toString() in CLIENT_ORDER_IDs: CLIENT_ORDER_IDs[sessionID.toString()].append(client_order_id.getValue()) else: CLIENT_ORDER_IDs[sessionID.toString()] = [client_order_id.getValue()] execution_reports = [] order_side = "b" if side.getValue() == "1" else "s" order = Order( symbol.getValue(), price.getValue(), quantity.getValue(), order_side, int(order_type.getValue()), client_order_id.getValue(), sessionID, ) MARKETS[market].replace_order(orig_client_order_id.getValue(), order) self.logger.debug("Processed replace order.") if MARKETS[market].trades.qsize() == 0: self.logger.debug("No trades.") execution_report = self._create_execution_report( symbol, side, client_order_id, price=price, quantity=quantity, exec_type=fix.ExecType_REPLACED, orig_client_order_id=orig_client_order_id, ) execution_reports.append((sessionID, execution_report)) FLUSH_BOOK[market] = [] else: while not MARKETS[market].trades.empty(): trade = MARKETS[market].trades.get() execution_report = self._handle_trade(symbol, trade, sessionID) if FLUSH_BOOK[market]: FLUSH_BOOK[market].append((trade.price, trade.quantity)) else: FLUSH_BOOK[market] = [(trade.price, trade.quantity)] if execution_report: execution_reports.append((trade.session, execution_report)) return execution_reports
def getExecutionReportForCancelOrder2(self, message): beginString = fix.BeginString() message.getHeader().getField(beginString) symbol = fix.Symbol() side = fix.Side() clOrdID = fix.ClOrdID() orderID = fix.OrderID() origClOrdID = fix.OrigClOrdID() message.getField(symbol) message.getField(side) message.getField(clOrdID) message.getField(orderID) message.getField(origClOrdID) executionReport = fix.Message() executionReport.getHeader().setField(beginString) executionReport.getHeader().setField( fix.MsgType(fix.MsgType_ExecutionReport)) data = {} data['id'] = orderID.getValue() response = cancelOrder(self.accessKey, self.secretKey, orderID.getValue()) jResponse = json.loads(response) executionReport.setField(fix.OrderID(orderID.getValue())) # todo get client order id executionReport.setField(clOrdID) executionReport.setField(fix.ExecID(self.genExecID())) if 'error' in jResponse and jResponse['error']: orderCancelReject = fix.Message() orderCancelReject.getHeader().setField(beginString) orderCancelReject.getHeader().setField( fix.MsgType(fix.MsgType_OrderCancelReject)) orderCancelReject.setField(clOrdID) orderCancelReject.setField(orderID) orderCancelReject.setField(origClOrdID) # todo reject reason orderCancelReject.setField(fix.OrdStatus( fix.OrdStatus_FILLED)) #39 = 2 FILLED orderCancelReject.setField( fix.CxlRejReason(0)) #102=0 TOO_LATE_TO_CANCEL orderCancelReject.setField( fix.CxlRejResponseTo(1)) #434=1 ORDER_CANCEL_REQUEST orderCancelReject.setField(fix.Text(jResponse['error']['message'])) return orderCancelReject else: executionReport.setField(fix.OrderID(str(jResponse['id']))) # todo check trades_count from json response and set FILL status? executionReport.setField(fix.OrdStatus(fix.OrdStatus_CANCELED)) executionReport.setField( fix.Side(fix.Side_BUY if jResponse['side'] == 'buy' else fix.Side_SELL)) executionReport.setField( fix.OrdType( fix.OrdType_LIMIT if jResponse['ord_type'] == 'limit' else fix.OrdType_MARKET)) #40=2 Limit order executionReport.setField(fix.Symbol(jResponse['market'])) executionReport.setField(fix.Price(float(jResponse['price']))) #44 executionReport.setField(fix.OrderQty(float( jResponse['volume']))) #38 executionReport.setField( fix.CumQty(float(jResponse['executed_volume']))) #14=100 executionReport.setField(fix.AvgPx(float( jResponse['avg_price']))) #6 executionReport.setField(fix.Text("Order cancelled!")) # Since FIX 4.3, ExecTransType values are moved to ExecType if beginString.getValue( ) == fix.BeginString_FIX40 or beginString.getValue( ) == fix.BeginString_FIX41 or beginString.getValue( ) == fix.BeginString_FIX42: executionReport.setField( fix.ExecTransType(fix.ExecTransType_CANCEL)) # ExecType and LeavesQty fields only existsince FIX 4.1 if beginString.getValue() >= fix.BeginString_FIX41: executionReport.setField(fix.ExecType( fix.ExecType_CANCELED)) #150=4 CANCELED executionReport.setField(fix.LeavesQty(0)) #151=0 return executionReport
def order_cancel(self, message, sessionID): self.logger.debug("Inside order delete.") orig_client_order_id = fix.OrigClOrdID() message.getField(orig_client_order_id) symbol = fix.Symbol() message.getField(symbol) side = fix.Side() message.getField(side) client_order_id = fix.ClOrdID() message.getField(client_order_id) execution_report = None market = symbol.getValue() if market not in MARKETS: execution_report = self._create_execution_report( symbol, side, client_order_id, text=f"Symbol {symbol.getValue()} not found.", exec_type=fix.ExecType_REJECTED, reject_reason=fix.OrdRejReason_UNKNOWN_SYMBOL, ) return [(sessionID, execution_report)] self.logger.debug(CLIENT_ORDER_IDs) if (sessionID.toString() not in CLIENT_ORDER_IDs) or ( orig_client_order_id.getValue() not in CLIENT_ORDER_IDs[sessionID.toString()] ): execution_report = self._create_execution_report( symbol, side, client_order_id, text=f"Client order ID {client_order_id.getValue()} not found.", exec_type=fix.ExecType_REJECTED, reject_reason=fix.OrdRejReason_UNKNOWN_ORDER, ) return [(sessionID, execution_report)] CLIENT_ORDER_IDs[sessionID.toString()].remove(orig_client_order_id.getValue()) execution_reports = [] MARKETS[market].delete_order(orig_client_order_id.getValue()) self.logger.debug("Processed delete order.") FLUSH_BOOK[market] = [] execution_report = self._create_execution_report( symbol, side, client_order_id, orig_client_order_id=orig_client_order_id, exec_type=fix.ExecType_CANCELLED, ) execution_reports.append((sessionID, execution_report)) return execution_reports