def __init__(self): Message.__init__(self) self.getHeader().setField(fix.MsgType("4"))
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 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 test_isAdmin(self): self.failUnless( self.object.isAdmin() == 0 ) self.object.getHeader().setField( fix.MsgType("A") ) assert( self.object.isAdmin() ) self.object.getHeader().setField( fix.MsgType("D") ) assert( self.object.isAdmin() == 0 )
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 toAdmin(self, message, session_id): msg_type = message.getHeader().getField(fix.MsgType()) if msg_type.getString() == fix.MsgType_Logon: self.client_fix_handler.handle_to_be_sent_logon_request(message)
def toApp(self, message, sessionID): print('Application - toApp', sessionID) print('message', message, '\n', self.get_header_value(message, fix.MsgType())) return
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 send_NewOrderSingle(self, order): if order.error: print( '[ERROR] The order cannot be sent because it contains errors.') return if order.ClOrdID is None: order.ClOrdID = self.app.next_ClOrdID() elif order.ClOrdID in self.Open_Orders.keys(): print( '[ERROR] Order not sent. There is already an open order with the same ID. Please use a different one or just leave it empty.' ) return message = fix.Message() header = message.getHeader() # Set message type to NewOrderSingle (35=D) header.setField(fix.MsgType(fix.MsgType_NewOrderSingle)) # Tag 11 - Unique ID to assign to this trade. message.setField(fix.ClOrdID(str(order.ClOrdID))) # Tag 1 - Account ID as provided by FIX administrator message.setField(fix.Account(self.account)) # Tag 55 message.setField(fix.Symbol(str(order.symbol))) # Tag 54 (1 == buy, 2 == sell) message.setField(fix.Side(str(order.side))) # Tag 38 message.setField(fix.OrderQty(int(order.quantity))) # Tag 40 (1 == market, 2 == limit) message.setField(fix.OrdType(str(order.type))) # Tag 44: not needed for market orders. if order.price is not None: message.setField(fix.Price(order.price)) # Tag 10000 - TTL in milliseconds for open trade expiration. message.setField(fix.IntField(10000, order.ttl)) # Tag 10001 (deviation: maximum allowed slippage) # Double value. Accepted deviation from the price submitted in tag 44. Only applicable if 40=2. # Defaults to 0.0. Setting this value to 0.00002 for a sell EURUSD limit order would allow for # execution on prices as low as 0.2 pips below the specified price. The preferred mode of operation # for limit orders is to set tag 44 at current market price and use tag 10001 to define a specific # slippage acceptance. if str(order.type) == '2': message.setField(fix.DoubleField(10001, order.deviation)) # Tag 60 (current time in UTC). 3 means 3 digits (milliseconds) message.setField(fix.TransactTime(3)) if self.sessionID_Trade is not None: # Add trade to local open orders: self.app.add_order(order) fix.Session.sendToTarget(message, self.sessionID_Trade) else: print( '[ERROR] send_NewOrderSingle() failed. sessionID_Trade is None!' )
def heartbeat(self): message = fix.Message() message.getHeader().setField(fix.MsgType(fix.MsgType_Heartbeat)) self.SocketInitiator.application.send(message)
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 put_order(self,security_type,symbol,currency,quantity,side,order_type,account,time_id,price=None): if quantity != 0 : trade = fix.Message() ''' STANDARD MESSAGE HEADER Required Tags: 8(BeginString) - 9(BodyLength) - 35(MsgType) - 49(SenderCompID) - 56(TargetCompID) - 34(MsgSeqNum) - 52(SendingTime) ''' trade.getHeader().setField(fix.BeginString(fix.BeginString_FIX42)) # trade.getHeader().setField(fix.MsgType(fix.MsgType_NewOrderSingle)) #39=D trade.getHeader().setField(fix.SendingTime(1)) # unique_order_id = self.genExecID() # print(f'Unique Order ID: {unique_order_id}') # trade.setField(fix.ClOrdID(unique_order_id)) #11=Unique order trade.setField(fix.HandlInst(fix.HandlInst_AUTOMATED_EXECUTION_ORDER_PUBLIC_BROKER_INTERVENTION_OK)) #21=3 (Manual order), 21=2 automated execution only supported value trade.setField(fix.Symbol(str(symbol))) #55 trade.setField(fix.Currency(str(currency))) #15 trade.setField(fix.SecurityType(str(security_type))) #167 trade.setField(fix.Side(str(side))) #54=1 Buy trade.setField(fix.OrdType(str(order_type))) #40=2 Limit order, 40=1 Market trade.setField(fix.OrderQty(quantity)) #38 if order_type != 1: #not market trade.setField(fix.Price(price)) # if market, this tag should be absent else: price = None trade.setField(fix.Account(str(account))) trade.setField(fix.ExDestination('IDEALPRO')) trade.setField(fix.CustomerOrFirm(0)) trade.setField(fix.ClOrdID(time_id+trade.getField(55)+trade.getField(15)+trade.getField(54))) #11= # trade.setField(fix.ClOrdID(datetime.datetime.utcnow().strftime('%Y%m%d%H%M%S')+trade.getField(55)+trade.getField(15)+trade.getField(54))) #11= # dnow = datetime.utcnow().strftime('%Y%m%d-%H:%M:%S') # tag = fix.TransactTime() #default = current time, SendingTime does the same thing # tag.setString(dnow.strftime('%Y%m%d-%H:%M:%S')) # trade.setField(tag) print(f'CREATING THE FOLLOWING ORDER:\n {trade.toString()}') fix.Session.sendToTarget(trade, self.sessionID) self.orders_dict[trade.getField(11)] = {#'id':trade.getField(11), #'datetime': trade.getField(11)[:12], 'account':trade.getField(1), 'symbol':trade.getField(55)+'.' + trade.getField(15), 'qty':trade.getField(38), 'ord_type':trade.getField(40), 'side':trade.getField(54), 'price':price, 'status':'sent' } else: print(f'QUANTITY IS 0!\nCHECK FOR STATUS OF LAST ORDER') if os.path.exists(f'{self.write_path}fix_orders.csv'): temp_orders = pd.read_csv(f'{self.write_path}fix_orders.csv',index_col=0) symbol_entries = temp_orders[temp_orders['symbol'] == symbol] last_symbol_entry = symbol_entries.iloc[-1] new_entry = last_symbol_entry new_id = time_id + last_symbol_entry.name[6:] new_entry.name = new_id temp_orders = temp_orders.append(last_symbol_entry,ignore_index=False) temp_orders.to_csv(f'{self.write_path}fix_orders.csv',) self.order_status_request(cl_ord_id=last_symbol_entry) # self.order_status_request(cl_ord_id=temp_orders.index[-1]) else: print(f'QUANTITY IS 0!\n FIX ORDERS FIRST RUN') time.sleep(100)
def onMessage(self, message, sessionID): # print("OnMessage %s" % message) msgType = fix.MsgType() message.getHeader().getField(msgType) if msgType.getValue() == "X": # print("MarketDataIncrementalRefresh %s" % message) noMDEntries = fix.NoMDEntries() message.getField(noMDEntries) if (noMDEntries.getValue() != 1): # print("NoMDEntries in MarketDataIncrementalRefresh is not 1!") return group = fix44.MarketDataIncrementalRefresh.NoMDEntries() message.getGroup(1, group) entryID = fix.MDEntryID() group.getField(entryID) action = fix.MDUpdateAction() group.getField(action) security = LAST_TRADE() security.MDEntryID = entryID.getValue() security.MDUpdateAction = action.getValue() symbol = fix.Symbol() if (group.isSetField(symbol)): group.getField(symbol) security.Symbol = symbol.getValue() entryType = fix.MDEntryType() if (group.isSetField(entryType)): group.getField(entryType) security.MDEntryType = entryType.getValue() price = fix.MDEntryPx() if (group.isSetField(price)): group.getField(price) security.MDEntryPx = price.getValue() size = fix.MDEntrySize() if (group.isSetField(size)): group.getField(size) security.MDEntrySize = size.getValue() qty = fix.MinQty() if (group.isSetField(qty)): group.getField(qty) security.MinQty = qty.getValue() fire(self.callback, "OnTradeUpdated", **{"trade": security}) if msgType.getValue() == 'W': book = BOOK() Symbol = fix.Symbol() message.getField(Symbol) book.symbol = Symbol.getValue() noMDEntries = fix.NoMDEntries() message.getField(noMDEntries) group = fix44.MarketDataSnapshotFullRefresh.NoMDEntries() MDEntryType = fix.MDEntryType() MDEntryPx = fix.MDEntryPx() MDEntrySize = fix.MDEntrySize() for i in range(1, noMDEntries.getValue()): message.getGroup(i, group) group.getField(MDEntryType) group.getField(MDEntryPx) group.getField(MDEntrySize) if MDEntryType.getValue() == '0': book.bid.append(MDEntryPx.getValue()) book.bid_size.append(MDEntrySize.getValue()) if MDEntryType.getValue() == '1': book.ask.append(MDEntryPx.getValue()) book.ask_size.append(MDEntrySize.getValue()) fire(self.callback, "OnBookUpdated", **{"book": book})
def onMessage(self, message, sessionID): print "OnMessage %s" % message msgType = fix.MsgType() message.getHeader().getField(msgType) if (msgType.getValue() == "X"): print "MarketDataIncrementalRefresh %s" % message noMDEntries = fix.NoMDEntries() message.getField(noMDEntries) if (noMDEntries.getValue() != 1): print "NoMDEntries in MarketDataIncrementalRefresh is not 1!" return group = fix44.MarketDataIncrementalRefresh.NoMDEntries() message.getGroup(1, group) entryID = fix.MDEntryID() group.getField(entryID) action = fix.MDUpdateAction() group.getField(action) actionvalue = action.getValue() #0=New, 1=Update, 2=Delete) if (actionvalue == '2'): #delete if entryID.getValue() in securities: del securities[entryID.getValue()] return security = SECURITY() security.MDEntryID = entryID.getValue() security.MDUpdateAction = action.getValue() symbol = fix.Symbol() if (group.isSetField(symbol)): group.getField(symbol) security.Symbol = symbol.getValue() entryType = fix.MDEntryType() if (group.isSetField(entryType)): group.getField(entryType) security.MDEntryType = entryType.getValue() price = fix.MDEntryPx() if (group.isSetField(price)): group.getField(price) security.MDEntryPx = price.getValue() size = fix.MDEntrySize() if (group.isSetField(size)): group.getField(size) security.MDEntrySize = size.getValue() qty = fix.MinQty() if (group.isSetField(qty)): group.getField(qty) security.MinQty = qty.getValue() inc = MinInc() if (message.isSetField(inc)): message.getField(inc) security.MinInc = inc.getValue() br = MinBr() if (message.isSetField(br)): message.getField(br) security.MinBR = br.getValue() ytm = YTM() if (message.isSetField(ytm)): message.getField(ytm) security.YTM = ytm.getValue() ytw = YTW() if (message.isSetField(ytw)): message.getField(ytw) security.YTW = ytw.getValue() print security securities[entryID.getValue()] = security
def fromApp(self, message, sessionID): self.pretty_print('fromApp', sessionID) print('Message:\n', message) print('Message type:', self.get_header_value(message, fix.MsgType()))