def top_n_orders(message, n): stock_id = getValue(message, 55) dict_list = give_top_n(stock_id, n) ret_message = fix44.MarketDataSnapshotFullRefresh() group = fix44.MarketDataSnapshotFullRefresh().NoMDEntries() for Dict in dict_list: group.setField(fix.MDEntryType(Dict["Type"])) group.setField(fix.MDEntryPx(Dict["Price"])) group.setField(fix.MDEntrySize(Dict["Quantity"])) group.setField(fix.OrderID(Dict["Order ID"])) ret_message.addGroup(group) ret_message.setField(55, stock_id) return ret_message
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 report_child_order(self, child_order: GenusChildOrder, trade: TradeData = None): """""" self.exec_id += 1 message = new_message(fix.MsgType_ExecutionReport) message.setField(fix.ClOrdID(child_order.cl_ord_id)) message.setField(fix.OrderID(child_order.order_id)) message.setField(fix.ExecID(str(self.exec_id))) message.setField(fix.OrdStatus(child_order.ord_status)) message.setField(fix.ExecType(child_order.ord_status)) message.setField(fix.Symbol(child_order.symbol)) message.setField(fix.Side(child_order.side)) message.setField(fix.OrderQty(child_order.order_qty)) message.setField(fix.CumQty(child_order.cum_qty)) message.setField( fix.LeavesQty(child_order.order_qty - child_order.cum_qty)) message.setField(fix.AvgPx(child_order.avg_px)) if trade: message.setField(fix.LastShares(trade.volume)) message.setField(fix.LastPx(trade.price)) fix.Session.sendToTarget(message, self.session_id)
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 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 getExecutionReportForNewOrder(self, message): beginString = fix.BeginString() message.getHeader().getField(beginString) symbol = fix.Symbol() side = fix.Side() ordType = fix.OrdType() orderQty = fix.OrderQty() price = fix.Price() clOrdID = fix.ClOrdID() message.getField(ordType) if ordType.getValue() != fix.OrdType_LIMIT: raise fix.IncorrectTagValue(ordType.getField()) message.getField(symbol) message.getField(side) message.getField(orderQty) message.getField(price) message.getField(clOrdID) executionReport = fix.Message() executionReport.getHeader().setField(beginString) executionReport.getHeader().setField( fix.MsgType(fix.MsgType_ExecutionReport)) executionReport.setField(fix.OrderID(self.genOrderID())) executionReport.setField(fix.ExecID(self.genExecID())) executionReport.setField(fix.OrdStatus(fix.OrdStatus_FILLED)) executionReport.setField(symbol) executionReport.setField(side) executionReport.setField(fix.CumQty(orderQty.getValue())) executionReport.setField(fix.AvgPx(price.getValue())) executionReport.setField(fix.LastShares(orderQty.getValue())) executionReport.setField(fix.LastPx(price.getValue())) executionReport.setField(clOrdID) executionReport.setField(orderQty) executionReport.setField(fix.Text("New order accepted!")) # Since FIX 4.3, ExecTransType is killed and the 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_NEW)) # ExecType and LeavesQty fields only existsince FIX 4.1 if beginString.getValue() >= fix.BeginString_FIX41: if beginString.getValue() <= fix.BeginString_FIX42: executionReport.setField(fix.ExecType( fix.ExecType_FILL)) #150=2 FILL (or 1 PARTIAL_FILL) else: # FILL and PARTIAL_FILL are removed and replaced by TRADE (F) since FIX 4.3 as these info can be retrieved from OrdStatus field executionReport.setField(fix.ExecType( fix.ExecType_TRADE)) #150=F TRADE executionReport.setField(fix.LeavesQty(0)) return executionReport
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 fromApp(self, message, sessionID): beginString = fix.BeginString() msgType = fix.MsgType() message.getHeader().getField(beginString) message.getHeader().getField(msgType) symbol = fix.Symbol() side = fix.Side() ordType = fix.OrdType() orderQty = fix.OrderQty() price = fix.Price() clOrdID = fix.ClOrdID() message.getField(ordType) print(ordType) if ordType.getValue() != fix.OrdType_LIMIT: raise fix.IncorrectTagValue(ordType.getField()) message.getField(symbol) message.getField(side) message.getField(orderQty) message.getField(price) message.getField(clOrdID) executionReport = fix.Message() executionReport.getHeader().setField(beginString) executionReport.getHeader().setField( fix.MsgType(fix.MsgType_ExecutionReport)) executionReport.setField(fix.OrderID(self.genOrderID())) executionReport.setField(fix.ExecID(self.genExecID())) executionReport.setField(fix.OrdStatus(fix.OrdStatus_FILLED)) executionReport.setField(symbol) executionReport.setField(side) executionReport.setField(fix.CumQty(orderQty.getValue())) executionReport.setField(fix.AvgPx(price.getValue())) executionReport.setField(fix.LastShares(orderQty.getValue())) executionReport.setField(fix.LastPx(price.getValue())) executionReport.setField(clOrdID) executionReport.setField(orderQty) if beginString.getValue( ) == fix.BeginString_FIX40 or beginString.getValue( ) == fix.BeginString_FIX41 or beginString.getValue( ) == fix.BeginString_FIX42: executionReport.setField(fix.ExecTransType(fix.ExecTransType_NEW)) if beginString.getValue() >= fix.BeginString_FIX41: executionReport.setField(fix.ExecType(fix.ExecType_FILL)) executionReport.setField(fix.LeavesQty(0)) try: fix.Session.sendToTarget(executionReport, sessionID) except (SessionNotFound, e): return
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 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 request_order(self): message = fix.Message() header = message.getHeader() header.setField(fix.BeginString(fix.BeginString_FIX42)) header.setField(fix.MsgType(fix.MsgType_OrderStatusRequest)) #35=H message.setField(fix.ClOrdID("*")) message.setField(fix.OrderID("375")) message.setField(fix.Side(fix.Side_BUY)) #54=1 Buy message.setField(fix.Symbol("ABCD")) #55=ABCD print(message.toString()) try: fix.Session.sendToTarget(message, self.sessionID) except (fix.ConfigError, fix.RuntimeError) as e: print(e)
def startFIXString(self, orderID): message = quickfix.Message() message.getHeader().setField(quickfix.BeginString(quickfix.BeginString_FIX42)) message.getHeader().setField(quickfix.MsgType(quickfix.MsgType_ExecutionReport)) message.getHeader().setField(quickfix.SendingTime()) message.getHeader().setField(quickfix.TransactTime()) message.setField(quickfix.ClOrdID(self.orders[orderID]['clOrdID'])) message.setField(quickfix.OrderQty(self.orders[orderID]['quantity'])) message.setField(quickfix.Symbol(self.orders[orderID]['symbol'])) message.setField(quickfix.Side(self.orders[orderID]['side'])) message.setField(quickfix.ExecID(str(self.getNextExecID(self.orders[orderID]['target'])))) if 'exchangeID' not in self.orders[orderID]: self.orders[orderID]['exchangeID'] = self.getNextExchangeID(self.orders[orderID]['target']) message.setField(quickfix.OrderID(str(self.orders[orderID]['exchangeID']))) return message
def getExecutionReportForStatusRequest(self, message): beginString = fix.BeginString() message.getHeader().getField(beginString) clOrdID = fix.ClOrdID() message.getField(clOrdID) executionReport = fix.Message() executionReport.getHeader().setField(beginString) executionReport.getHeader().setField( fix.MsgType(fix.MsgType_ExecutionReport)) executionReport.setField(fix.Symbol("ABCD")) executionReport.setField(fix.Side(fix.Side_BUY)) #43=1 Buy executionReport.setField(fix.OrderID(self.genOrderID())) executionReport.setField(fix.ExecID(self.genExecID())) executionReport.setField(fix.OrdType( fix.OrdType_LIMIT)) #40=2 Limit order executionReport.setField(fix.OrderQty(100)) #38=100 executionReport.setField(fix.Price(10)) #44=10 executionReport.setField(fix.OrdStatus(fix.OrdStatus_FILLED)) executionReport.setField(fix.AvgPx(10)) #6=10 executionReport.setField(fix.CumQty(100)) #14=100 executionReport.setField(clOrdID) executionReport.setField(fix.Text("Order status retrieved!")) # 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_STATUS)) # ExecType and LeavesQty fields only existsince FIX 4.1 if beginString.getValue() >= fix.BeginString_FIX41: if beginString.getValue() <= fix.BeginString_FIX42: executionReport.setField(fix.ExecType( fix.ExecType_FILL)) #150=2 FILL (or 1 PARTIAL_FILL) else: # FILL and PARTIAL_FILL are removed and replaced by TRADE (F) since FIX 4.3 as these info can be retrieved from OrdStatus field executionReport.setField(fix.ExecType( fix.ExecType_TRADE)) #150=F TRADE executionReport.setField(fix.LeavesQty(0)) return executionReport
def getExecutionReportForCancelOrder(self, message): beginString = fix.BeginString() message.getHeader().getField(beginString) symbol = fix.Symbol() side = fix.Side() clOrdID = fix.ClOrdID() message.getField(symbol) message.getField(side) message.getField(clOrdID) executionReport = fix.Message() executionReport.getHeader().setField(beginString) executionReport.getHeader().setField( fix.MsgType(fix.MsgType_ExecutionReport)) executionReport.setField(fix.OrderID(self.genOrderID())) executionReport.setField(fix.ExecID(self.genExecID())) executionReport.setField(fix.OrdType( fix.OrdType_LIMIT)) #40=2 Limit order executionReport.setField(fix.OrderQty(100)) #38=100 executionReport.setField(fix.Price(10)) #44=10 executionReport.setField(fix.OrdStatus(fix.OrdStatus_FILLED)) executionReport.setField(symbol) executionReport.setField(side) executionReport.setField(fix.AvgPx(10)) #6=10 executionReport.setField(fix.CumQty(100)) #14=100 executionReport.setField(clOrdID) 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 new_order(self, message, beginString, sessionID): symbol = fix.Symbol() side = fix.Side() ordType = fix.OrdType() orderQty = fix.OrderQty() price = fix.Price(50) clOrdID = fix.ClOrdID() message.getField(ordType) message.getField(symbol) message.getField(side) message.getField(orderQty) message.getField(price) message.getField(clOrdID) log.info("new_order:\nordType:{},symbol:{},side:{},orderQty:{},price:{},clOrdID:{} -----"\ .format(ordType, symbol, side, orderQty, price, clOrdID)) executionReport = fix.Message() executionReport.getHeader().setField(beginString) executionReport.getHeader().setField( fix.MsgType(fix.MsgType_ExecutionReport)) executionReport.setField(fix.TransactTime()) executionReport.setField(fix.OrderID(self.genOrderID())) executionReport.setField(fix.ExecID(self.genExecID())) executionReport.setField(fix.OrdStatus(fix.OrdStatus_NEW)) executionReport.setField(symbol) executionReport.setField(side) executionReport.setField(fix.CumQty(orderQty.getValue())) executionReport.setField(fix.AvgPx(price.getValue())) executionReport.setField(fix.LastShares(orderQty.getValue())) executionReport.setField(fix.LastPx(price.getValue())) executionReport.setField(clOrdID) executionReport.setField(orderQty) executionReport.setField(fix.ExecType(fix.ExecType_NEW)) executionReport.setField(fix.LeavesQty(orderQty.getValue())) try: fix.Session.sendToTarget(executionReport, sessionID) time.sleep(1) if ordType.getValue() == fix.OrdType_MARKET: executionReport.setField(fix.OrdStatus(fix.OrdStatus_FILLED)) executionReport.setField(fix.ExecType(fix.ExecType_TRADE)) fix.Session.sendToTarget(executionReport, sessionID) except fix.SessionNotFound as e: return
def _process_order_cancel_reject(self, message): cl_ord_id = self._extract_field(fix.ClOrdID(), message) market_order_id = self._extract_field(fix.OrderID(), message) cxl_rej_response_to = self._extract_field(fix.CxlRejResponseTo(), message) order = self.order_store.find_order(cl_ord_id, market_order_id) if cxl_rej_response_to == \ CxlRejResponseTo.ORDER_CANCEL_REPLACE_REQUEST: order.status = OrdStatus.REPLACE_REJECT self.order_handler.on_replace_rej(order) elif cxl_rej_response_to == CxlRejResponseTo.ORDER_CANCEL_REQUEST: order.status = OrdStatus.CANCEL_REJECT self.order_handler.on_cancel_rej(order) else: self.log.error('Unknown CxlRejResponseTo value: {}'.format( cxl_rej_response_to))
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 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 getExecutionReportForNewOrder2(self, message): beginString = fix.BeginString() message.getHeader().getField(beginString) msgSeqNum = fix.MsgSeqNum() message.getHeader().getField(msgSeqNum) symbol = fix.Symbol() side = fix.Side() ordType = fix.OrdType() orderQty = fix.OrderQty() price = fix.Price() clOrdID = fix.ClOrdID() message.getField(ordType) # todo handle market order if ordType.getValue() != fix.OrdType_LIMIT: raise fix.IncorrectTagValue(ordType.getField()) message.getField(symbol) message.getField(side) message.getField(orderQty) message.getField(price) message.getField(clOrdID) data = {} data['market'] = symbol.getValue() data['price'] = price.getValue() data['side'] = 'buy' if side.getValue() == fix.Side_BUY else 'sell' data['volume'] = orderQty.getValue() response = createOrder(self.accessKey, self.secretKey, data) jResponse = json.loads(response) executionReport = fix.Message() executionReport.getHeader().setField(beginString) executionReport.getHeader().setField( fix.MsgType(fix.MsgType_ExecutionReport)) # todo exec id? executionReport.setField(fix.ExecID(self.genExecID())) executionReport.setField(symbol) executionReport.setField(side) executionReport.setField(fix.CumQty(orderQty.getValue())) executionReport.setField(fix.AvgPx(price.getValue())) executionReport.setField(fix.LastShares(orderQty.getValue())) executionReport.setField(fix.LastPx(price.getValue())) # todo save Client order id to DB? executionReport.setField(clOrdID) executionReport.setField(orderQty) if 'error' in jResponse and jResponse['error']: executionReport.setField(fix.OrderID("nil")) executionReport.setField(fix.OrdStatus(fix.OrdStatus_REJECTED)) executionReport.setField(fix.Text(jResponse['error']['message'])) # todo Reject reason for each case executionReport.setField( fix.OrdRejReason(fix.OrdRejReason_UNKNOWN_SYMBOL)) 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_NEW)) executionReport.setField(fix.Text('New order accpeted!')) # Since FIX 4.3, ExecTransType is killed and the 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_NEW)) # todo check trades_count from json response and set FILL status? # ExecType and LeavesQty fields only existsince FIX 4.1 if beginString.getValue() >= fix.BeginString_FIX41: if beginString.getValue() <= fix.BeginString_FIX42: executionReport.setField(fix.ExecType( fix.ExecType_FILL)) #150=2 FILL (or 1 PARTIAL_FILL) else: # FILL and PARTIAL_FILL are removed and replaced by TRADE (F) since FIX 4.3 as these info can be retrieved from OrdStatus field executionReport.setField(fix.ExecType( fix.ExecType_TRADE)) #150=F TRADE executionReport.setField(fix.LeavesQty(0)) """if 'error' in jResponse and jResponse['error']: reject = fix.Message() reject.getHeader().setField(beginString) reject.getHeader().setField(fix.MsgType(fix.MsgType_Reject)) reject.setField(fix.RefMsgType(fix.MsgType_NewOrderSingle)) reject.setField(fix.RefSeqNum(msgSeqNum.getValue())) #45 = RefSeqNum reject.setField(fix.SessionRejectReason(fix.SessionRejectReason_OTHER)) #373 = 99 OTHER reject.setField(fix.Text(jResponse['message'])) return reject """ return executionReport
def onNewOrderSingle(self, message, beginString, sessionID): symbol = quickfix.Symbol() side = quickfix.Side() ordType = quickfix.OrdType() orderQty = quickfix.OrderQty() price = quickfix.Price() clOrdID = quickfix.ClOrdID() quoteID = quickfix.QuoteID() currency = quickfix.Currency() message.getField(ordType) if ordType.getValue() != quickfix.OrdType_PREVIOUSLY_QUOTED: raise quickfix.IncorrectTagValue(ordType.getField()) message.getField(symbol) message.getField(side) message.getField(orderQty) message.getField(price) message.getField(clOrdID) message.getField(quoteID) message.getField(currency) executionReport = quickfix.Message() executionReport.getHeader().setField(beginString) executionReport.getHeader().setField( quickfix.MsgType(quickfix.MsgType_ExecutionReport)) executionReport.setField(quickfix.OrderID(self.idGen.orderID())) executionReport.setField(quickfix.ExecID(self.idGen.execID())) try: reject_chance = random.choice(range(1, 101)) if self.rejectRate > reject_chance: raise FixSimError("Rejected by cruel destiny %s" % str( (reject_chance, self.rejectRate))) subscription = self.subscriptions.get(symbol.getValue()) quote = subscription.orderbook.get(quoteID.getValue()) execPrice = price.getValue() execSize = orderQty.getValue() if execSize > quote.size: raise FixSimError("size to large for quote") if abs(execPrice - quote.price) > 0.0000001: raise FixSimError("Trade price not equal to quote") executionReport.setField( quickfix.SettlDate(self.getSettlementDate())) executionReport.setField(quickfix.Currency(subscription.currency)) executionReport.setField( quickfix.OrdStatus(quickfix.OrdStatus_FILLED)) executionReport.setField(symbol) executionReport.setField(side) executionReport.setField(clOrdID) executionReport.setField(quickfix.Price(price.getValue())) executionReport.setField(quickfix.AvgPx(execPrice)) executionReport.setField(quickfix.LastPx(execPrice)) executionReport.setField(quickfix.LastShares(execSize)) executionReport.setField(quickfix.CumQty(execSize)) executionReport.setField(quickfix.OrderQty(execSize)) executionReport.setField(quickfix.ExecType(quickfix.ExecType_FILL)) executionReport.setField(quickfix.LeavesQty(0)) except Exception as e: self.logger.exception("FixServer:Close order error") executionReport.setField(quickfix.SettlDate('')) executionReport.setField(currency) executionReport.setField( quickfix.OrdStatus(quickfix.OrdStatus_REJECTED)) executionReport.setField(symbol) executionReport.setField(side) executionReport.setField(clOrdID) executionReport.setField(quickfix.Price(0)) executionReport.setField(quickfix.AvgPx(0)) executionReport.setField(quickfix.LastPx(0)) executionReport.setField(quickfix.LastShares(0)) executionReport.setField(quickfix.CumQty(0)) executionReport.setField(quickfix.OrderQty(0)) executionReport.setField( quickfix.ExecType(quickfix.ExecType_REJECTED)) executionReport.setField(quickfix.LeavesQty(0)) self.sendToTarget(executionReport, sessionID)
class Application(fix.Application): orderID = 0 execID = 0 bids = {} asks = {} #creates empty dictionaries loc = ("C:\\Bloomberg\\SampleMarketData.xlsx") wb = xlrd.open_workbook(loc) sheetMSFT = wb.sheet_by_index(0) sheetNFLX = wb.sheet_by_index(1) sheetNames = wb.sheet_names() xl_sheet1 = wb.sheet_by_index(0) xl_sheet2 = wb.sheet_by_index(1) sheet1Name = xl_sheet1.name.encode("utf-8") sheet2Name = xl_sheet2.name.encode("utf-8") excelbids = {} excelbids['BATS'] = {} excelbids['BATS'][sheet1Name] = {} excelbids['BATS'][sheet2Name] = {} excelbids['NASD'] = {} excelbids['NASD'][sheet1Name] = {} excelbids['NASD'][sheet2Name] = {} excelasks = {} excelasks['BATS'] = {} excelasks['BATS'][sheet1Name] = {} excelasks['BATS'][sheet2Name] = {} excelasks['NASD'] = {} excelasks['NASD'][sheet1Name] = {} excelasks['NASD'][sheet2Name] = {} for i in range (2, 7): for j in range (0, 1): excelbids['NASD'][sheet1Name][sheetMSFT.cell_value(i, j)] = sheetMSFT.cell_value(i, j+1) for i in range (2, 7): for j in range (2, 3): excelasks['NASD'][sheet1Name][sheetMSFT.cell_value(i, j)] = sheetMSFT.cell_value(i, j+1) for i in range (9, 14): for j in range (0, 1): excelbids['BATS'][sheet1Name][sheetMSFT.cell_value(i, j)] = sheetMSFT.cell_value(i, j+1) for i in range (9, 14): for j in range (2, 3): excelasks['BATS'][sheet1Name][sheetMSFT.cell_value(i, j)] = sheetMSFT.cell_value(i, j+1) for i in range (2, 7): for j in range (0, 1): excelbids['NASD'][sheet2Name][sheetNFLX.cell_value(i, j)] = sheetNFLX.cell_value(i, j+1) for i in range (2, 7): for j in range (2, 3): excelasks['NASD'][sheet2Name][sheetNFLX.cell_value(i, j)] = sheetNFLX.cell_value(i, j+1) for i in range (9, 14): for j in range (0, 1): excelbids['BATS'][sheet2Name][sheetNFLX.cell_value(i, j)] = sheetNFLX.cell_value(i, j+1) for i in range (9, 14): for j in range (2, 3): excelasks['BATS'][sheet2Name][sheetNFLX.cell_value(i, j)] = sheetNFLX.cell_value(i, j+1) #reads excel files, inputs data into nested dictionaries @echo def onCreate(self, sessionID): return @echo def onLogon(self, sessionID): return @echo def onLogout(self, sessionID): return @echo def toAdmin(self, sessionID, message): return @echo def fromAdmin(self, sessionID, message): return @echo def toApp(self, sessionID, message): return @echo 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 if msgType.getValue() == 'D': print 'New Order Single' symbol = fix.Symbol() side = fix.Side() ordType = fix.OrdType() orderQty = fix.OrderQty() price = fix.Price() timeInForce = fix.TimeInForce() clOrdID = fix.ClOrdID() message.getField( ordType ) print message if ordType.getValue() == fix.OrdType_LIMIT: message.getField( price ) price = round(float(price.getValue()),2) message.getField( symbol ) message.getField( side ) message.getField( orderQty ) message.getField( clOrdID ) message.getField( timeInForce ) executionReport = fix.Message() executionReport.getHeader().setField( beginString ) executionReport.getHeader().setField( fix.MsgType(fix.MsgType_ExecutionReport) ) availableQty = 0 if side.getValue() == '2': #check the bids sym = symbol.getValue() mergedDict = sorted(set(self.excelbids['BATS'][sym].keys()) | set(self.excelbids['NASD'][sym].keys()), reverse = True) orderMergedDict = OrderedDict() for pricelevel in mergedDict: orderMergedDict[pricelevel] = OrderedDict() if pricelevel in self.excelbids['BATS'][sym].keys(): orderMergedDict[pricelevel]['BATS'] = self.excelbids['BATS'][sym][pricelevel] if pricelevel in self.excelbids['NASD'][sym].keys(): orderMergedDict[pricelevel]['NASD'] = self.excelbids['NASD'][sym][pricelevel] print '-------------Sell Order - Checking available Bids-------------' qty = orderQty.getValue() orderToSend = {} for bid_price, exch in orderMergedDict.iteritems(): if price <= bid_price or ordType.getValue() == fix.OrdType_MARKET : for exchange,bid_qty in exch.iteritems(): if exchange not in orderToSend: orderToSend[exchange] = {} if bid_qty >= qty and qty > 0: orderToSend[exchange][bid_price] = qty qty = 0 elif qty > 0: orderToSend[exchange][bid_price] = bid_qty qty = qty - bid_qty availableQty += bid_qty else: #check the asks sym = symbol.getValue() mergedDict = sorted(set(self.excelasks['BATS'][sym].keys()) | set(self.excelasks['NASD'][sym].keys())) orderMergedDict = OrderedDict() for pricelevel in mergedDict: orderMergedDict[pricelevel] = OrderedDict() if pricelevel in self.excelasks['BATS'][sym].keys(): orderMergedDict[pricelevel]['BATS'] = self.excelasks['BATS'][sym][pricelevel] if pricelevel in self.excelasks['NASD'][sym].keys(): orderMergedDict[pricelevel]['NASD'] = self.excelasks['NASD'][sym][pricelevel] print '--------------Buy Order - Checking available Asks-------------' qty = orderQty.getValue() orderToSend = {} for ask_price, exch in orderMergedDict.iteritems(): #if ask_price <= round(float(price.getValue()),2): if ask_price <= price or ordType.getValue() == fix.OrdType_MARKET: for exchange,ask_qty in exch.iteritems(): if exchange not in orderToSend: orderToSend[exchange] = {} if ask_qty >= qty and qty > 0: orderToSend[exchange][ask_price] = qty qty = 0 elif qty > 0: orderToSend[exchange][ask_price] = ask_qty qty = qty - ask_qty availableQty += ask_qty filledQty = 0 if len(orderToSend) > 0: for exchange, detailsOfOrders in orderToSend.iteritems(): for price, qty in detailsOfOrders.iteritems(): filledQty = filledQty + qty executionReport.setField( fix.OrderID(self.genOrderID()) ) executionReport.setField( fix.ExecID(self.genExecID()) ) if filledQty >= orderQty.getValue(): executionReport.setField( fix.OrdStatus(fix.OrdStatus_FILLED) ) else: executionReport.setField( fix.OrdStatus(fix.OrdStatus_PARTIALLY_FILLED) ) executionReport.setField( symbol ) executionReport.setField( side ) executionReport.setField( fix.CumQty(filledQty)) executionReport.setField( fix.AvgPx(price )) # to do - need to properly calculate average price executionReport.setField( fix.LastShares(qty)) executionReport.setField( fix.LastPx(price)) executionReport.setField( clOrdID ) executionReport.setField( orderQty ) executionReport.setField( fix.LastMkt(exchange)) if beginString.getValue() == fix.BeginString_FIX40 or beginString.getValue() == fix.BeginString_FIX41 or beginString.getValue() == fix.BeginString_FIX42: executionReport.setField( fix.ExecTransType(fix.ExecTransType_NEW) ) if beginString.getValue() >= fix.BeginString_FIX41: if filledQty >=0 : executionReport.setField( fix.ExecType(fix.ExecType_FILL) ) executionReport.setField( fix.LeavesQty(0) ) else: executionReport.setField( fix.ExecType(fix.ExecType_PARTIAL_FILL) ) executionReport.setField( fix.LeavesQty(orderQty.getValue() - filledQty) ) try: print executionReport fix.Session.sendToTarget( executionReport, sessionID ) except SessionNotFound, e: return if timeInForce.getValue() == fix.TimeInForce_IMMEDIATE_OR_CANCEL: print "TimeInForce is IOC - need to cancel the remaining balance" 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( fix.ExecID(self.genExecID()) ) executionReport.setField( fix.OrderID(self.genOrderID()) ) executionReport.setField( fix.AvgPx(price)) executionReport.setField( fix.LastShares(0)) executionReport.setField( fix.CumQty(filledQty)) executionReport.setField( fix.LastPx(price)) executionReport.setField( orderQty ) 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 fromApp(self, message, sessionID): print('::::fromApp called::::') conn = sqlite3.connect('rtmd.db') c = conn.cursor() c.execute(''' create table if not exists ask( orderId text primary key unique, price int, quantity int, company text, exchange text, time text ); ''') c.execute(''' create table if not exists bid( orderId text primary key unique, price int, quantity int, company text, exchange text, time text ); ''') class order: def __init__(self, id, price, type, qty, company, exchg, time): self.id = id self.price = price self.type = type self.qty = qty self.company = company self.exchg = exchg self.time = time group = fix44.MarketDataSnapshotFullRefresh().NoMDEntries() #orderList = [] #to store each order entry sent in an object of <class 'order'> in order to send to UI team orderID = fix.OrderID() #represents orderID MDEntryType = fix.MDEntryType() NumberOfOrders = fix.NumberOfOrders() #represents quantity MDEntryPx = fix.MDEntryPx() #represents the price MDEntrySeller = fix.MDEntrySeller() #represents company MDMkt = fix.MDMkt() #represents exchange #MDEntrytime = fix.MDEntryTime() #represents time noMDEntries = fix.NoMDEntries( ) #get the total number of groups in snapshot message.getField(noMDEntries) tag, numberOfGroups = str(noMDEntries).split('=') numberOfGroups = numberOfGroups[:-1] numberOfGroups = int(numberOfGroups) for i in range(1, numberOfGroups + 1): message.getGroup(i, group) tag, type = str(group.getField(MDEntryType)).split( '=') #storing order type in var 'type' type = type[:-1] #to ignore the last special character tag, price = str(group.getField(MDEntryPx)).split('=') price = price[:-1] tag, id = str(group.getField(orderID)).split('=') id = id[:-1] tag, qty = str(group.getField(NumberOfOrders)).split('=') qty = qty[:-1] tag, company = str(group.getField(MDEntrySeller)).split('=') company = company[:-1] tag, exchg = str(group.getField(MDMkt)).split('=') exchg = exchg[:-1] # tag, time = str(group.getField(MDEntrytime)).split('=') # time = time[:-1] time = '2020-06-12 15:02:30' orderc = order(id, price, type, qty, company, exchg, time) print(orderc.id, orderc.price, orderc.qty, orderc.company, orderc.exchg, end=' ') print(' :: will be put in table ' + str(orderc.type)) params = (orderc.id, orderc.price, orderc.qty, orderc.company, orderc.exchg, orderc.time) if (orderc.type == '0'): c.execute("insert or ignore into ask values(?, ?, ?, ?, ?, ?)", params) elif (orderc.type == '1'): c.execute("insert or ignore into bid values(?, ?, ?, ?, ?, ?)", params) print('ask table has: ') for row in c.execute("select * from ask"): print(row) print() print('bid table has: ') for row in c.execute("select * from bid"): print(row) conn.commit() conn.close() return
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))
def run(self): message = fix44.MarketDataSnapshotFullRefresh() group = fix44.MarketDataSnapshotFullRefresh().NoMDEntries() group.setField(fix.MDEntryType('0')) group.setField(fix.MDEntryPx(12.32)) group.setField(fix.MDEntrySize(100)) group.setField(fix.OrderID("ORDERID")) group.setField(fix.NumberOfOrders(1000)) group.setField(fix.MDEntrySeller('RIL')) group.setField(fix.MDMkt('BSE')) #group.setField(fix.MDEntryTime(20200723)) message.addGroup(group) group.setField(fix.MDEntryType('0')) group.setField(fix.MDEntryPx(12.32)) group.setField(fix.MDEntrySize(100)) group.setField(fix.OrderID("ORDERID")) group.setField(fix.NumberOfOrders(1000)) group.setField(fix.MDEntrySeller('RIL')) group.setField(fix.MDMkt('BSE')) # group.setField(fix.MDEntryTime(20200723)) message.addGroup(group) group.setField(fix.MDEntryType('1')) group.setField(fix.MDEntryPx(12.34)) group.setField(fix.MDEntrySize(104)) group.setField(fix.OrderID("ORDERID2")) group.setField(fix.NumberOfOrders(9087)) group.setField(fix.MDEntrySeller('BHEL')) group.setField(fix.MDMkt('NSE')) # group.setField(fix.MDEntryTime(20200429)) message.addGroup(group) group.setField(fix.MDEntryType('1')) group.setField(fix.MDEntryPx(12.34)) group.setField(fix.MDEntrySize(104)) group.setField(fix.OrderID("ORDERID2")) group.setField(fix.NumberOfOrders(9087)) group.setField(fix.MDEntrySeller('BHEL')) group.setField(fix.MDMkt('NSE')) # group.setField(fix.MDEntryTime(20200429)) message.addGroup(group) group.setField(fix.MDEntryType('0')) group.setField(fix.MDEntryPx(18.92)) group.setField(fix.MDEntrySize(2000)) group.setField(fix.OrderID("ORDERID3")) group.setField(fix.NumberOfOrders(10050)) group.setField(fix.MDEntrySeller('TCS')) group.setField(fix.MDMkt('BSE')) # group.setField(fix.MDEntryTime(20200723)) message.addGroup(group) group.setField(fix.MDEntryType('0')) group.setField(fix.MDEntryPx(200.32)) group.setField(fix.MDEntrySize(1006)) group.setField(fix.OrderID("ORDERID4")) group.setField(fix.NumberOfOrders(1000)) group.setField(fix.MDEntrySeller('Credit Suisse')) group.setField(fix.MDMkt('BSE')) # group.setField(fix.MDEntryTime(20200723)) message.addGroup(group) group.setField(fix.MDEntryType('0')) group.setField(fix.MDEntryPx(1000)) group.setField(fix.MDEntrySize(100)) group.setField(fix.OrderID("ORDERID6")) group.setField(fix.NumberOfOrders(1000)) group.setField(fix.MDEntrySeller('Aramco')) group.setField(fix.MDMkt('BSE')) # group.setField(fix.MDEntryTime(20200723)) message.addGroup(group) group.setField(fix.MDEntryType('1')) group.setField(fix.MDEntryPx(12.67)) group.setField(fix.MDEntrySize(1045)) group.setField(fix.OrderID("ORDERID7")) group.setField(fix.NumberOfOrders(8960)) group.setField(fix.MDEntrySeller('Zomato')) group.setField(fix.MDMkt('NSE')) # group.setField(fix.MDEntryTime(20200429)) message.addGroup(group) group.setField(fix.MDEntryType('1')) group.setField(fix.MDEntryPx(129)) group.setField(fix.MDEntrySize(10894)) group.setField(fix.OrderID("ORDERID8")) group.setField(fix.NumberOfOrders(9076)) group.setField(fix.MDEntrySeller('Gilbarco')) group.setField(fix.MDMkt('NSE')) # group.setField(fix.MDEntryTime(20200429)) message.addGroup(group) group.setField(fix.MDEntryType('1')) group.setField(fix.MDEntryPx(198)) group.setField(fix.MDEntrySize(1034)) group.setField(fix.OrderID("ORDERID9")) group.setField(fix.NumberOfOrders(9087)) group.setField(fix.MDEntrySeller('Huwawei')) group.setField(fix.MDMkt('NSE')) # group.setField(fix.MDEntryTime(20200429)) message.addGroup(group) fix.Session_sendToTarget(message, self.sessionID) return
def getExecutionReportForStatusRequest2(self, message): beginString = fix.BeginString() message.getHeader().getField(beginString) clOrdID = fix.ClOrdID() orderID = fix.OrderID() message.getField(clOrdID) message.getField(orderID) response = getOrder(self.accessKey, self.secretKey, orderID.getValue()) jResponse = json.loads(response) executionReport = fix.Message() executionReport.getHeader().setField(beginString) executionReport.getHeader().setField( fix.MsgType(fix.MsgType_ExecutionReport)) executionReport.setField(fix.ExecID(self.genExecID())) # todo get client order id executionReport.setField(clOrdID) if 'error' in jResponse and jResponse['error']: executionReport.setField(fix.OrderID(orderID.getValue())) executionReport.setField(fix.OrdStatus(fix.OrdStatus_REJECTED)) executionReport.setField(fix.Text(jResponse['error']['message'])) # todo Reject reason for each case executionReport.setField( fix.OrdRejReason(fix.OrdRejReason_UNKNOWN_ORDER)) 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_NEW)) 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 status retrieved!')) # 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_STATUS)) # ExecType and LeavesQty fields only existsince FIX 4.1 if beginString.getValue() >= fix.BeginString_FIX41: if beginString.getValue() <= fix.BeginString_FIX42: executionReport.setField(fix.ExecType( fix.ExecType_FILL)) #150=2 FILL (or 1 PARTIAL_FILL) else: # FILL and PARTIAL_FILL are removed and replaced by TRADE (F) since FIX 4.3 as these info can be retrieved from OrdStatus field executionReport.setField(fix.ExecType( fix.ExecType_TRADE)) #150=F TRADE executionReport.setField(fix.LeavesQty(0)) return executionReport
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