Exemplo n.º 1
0
    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)
Exemplo n.º 5
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