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 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 onMarketDataRequest(self, message, sessionID): requestID = quickfix.MDReqID() try: message.getField(requestID) except Exception as e: raise quickfix.IncorrectTagValue(requestID) try: relatedSym = self.fixVersion.MarketDataRequest.NoRelatedSym() symbolFix = quickfix.Symbol() product = quickfix.Product() message.getGroup(1, relatedSym) relatedSym.getField(symbolFix) relatedSym.getField(product) if product.getValue() != quickfix.Product_CURRENCY: self.sendMarketDataReject( requestID, " product.getValue() != quickfix.Product_CURRENCY:", sessionID) return # bid entryType = self.fixVersion.MarketDataRequest.NoMDEntryTypes() message.getGroup(1, entryType) # ask message.getGroup(2, entryType) symbol = symbolFix.getValue() subscription = self.subscriptions.get(symbol) if subscription is None: self.sendMarketDataReject(requestID, "Unknown symbol: %s" % str(symbol), sessionID) return subscription.addSession(sessionID) except Exception as e: print e, e.args self.sendMarketDataReject(requestID, str(e), sessionID)
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)
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