Example #1
0
    def decode(self, rawmsg):
        #msg = rawmsg.rstrip(os.linesep).split(SOH)
        try:
            rawmsg = rawmsg.decode('utf-8')
            msg = rawmsg.split(self.SOH)
            msg = msg[:-1]

            if len(msg) < 3: # at a minumum we require BeginString, BodyLength & Checksum
                return (None, 0)

            tag, value = msg[0].split('=', 1)
            if tag != self.protocol.fixtags.BeginString:
                logging.error("*** BeginString missing or not 1st field *** [" + tag + "]")
            elif value != self.protocol.beginstring:
                logging.error("FIX Version unexpected (Recv: %s Expected: %s)" % (value, self.protocol.beginstring))

            tag, value = msg[1].split('=', 1)
            msgLength = len(msg[0]) + len(msg[1]) + len('10=000') + 3
            if tag != self.protocol.fixtags.BodyLength:
                logging.error("*** BodyLength missing or not 2nd field *** [" + tag + "]")
            else:
                msgLength += int(value)

            # do we have a complete message on the sockt
            if msgLength > len(rawmsg):
                return (None, 0)
            else:
                remainingMsgFragment = msgLength

                # resplit our message
                msg = rawmsg[:msgLength].split(self.SOH)
                msg = msg[:-1]
                decodedMsg = FIXMessage("UNKNOWN")

                # logging.debug("\t-----------------------------------------")
                # logging.debug("\t" + "|".join(msg))

                repeatingGroups = []
                repeatingGroupTags = self.protocol.fixtags.repeatingGroupIdentifiers()
                currentContext = decodedMsg

                for m in msg:
                    tag, value = m.split('=', 1)
                    t = None
                    try:
                        t = self.protocol.fixtags.tagToName(tag)
                    except KeyError:
                        logging.info("\t%s(Unknown): %s" % (tag, value))
                        t = "{unknown}"

                    if tag == self.protocol.fixtags.CheckSum:
                        cksum = ((sum([ord(i) for i in list(self.SOH.join(msg[:-1]))]) + 1) % 256)
                        if cksum != int(value):
                            logging.warning("\tCheckSum: %s (INVALID) expecting %s" % (int(value), cksum))
                    elif tag == self.protocol.fixtags.MsgType:
                        try:
                            msgType =  self.protocol.msgtype.msgTypeToName(value)
                            decodedMsg.setMsgType(value)
                        except KeyError:
                            logging.error('*** MsgType "%s" not supported ***')

                    if tag in repeatingGroupTags: # found the start of a repeating group
                        if type(currentContext) is RepeatingGroupContext: # i.e. we are already in a repeating group
                            while repeatingGroups and tag not in currentContext.repeatingGroupTags:
                                currentContext.parent.addRepeatingGroup(currentContext.tag, currentContext)
                                currentContext = currentContext.parent
                                del repeatingGroups[-1] # pop the completed group off the stack

                        ctx = RepeatingGroupContext(tag, repeatingGroupTags[tag], currentContext)
                        repeatingGroups.append(ctx)
                        currentContext = ctx
                    elif repeatingGroups: # we have 1 or more repeating groups in progress & our tag isn't the start of a group
                        while repeatingGroups and tag not in currentContext.repeatingGroupTags:
                            currentContext.parent.addRepeatingGroup(currentContext.tag, currentContext)
                            currentContext = currentContext.parent
                            del repeatingGroups[-1] # pop the completed group off the stack

                        if tag in currentContext.tags:
                            # if the repeating group already contains this field, start the next
                            currentContext.parent.addRepeatingGroup(currentContext.tag, currentContext)
                            ctx = RepeatingGroupContext(currentContext.tag, currentContext.repeatingGroupTags, currentContext.parent)
                            del repeatingGroups[-1] # pop the completed group off the stack
                            repeatingGroups.append(ctx)
                            currentContext = ctx

                        # else add it to the current one
                        currentContext.setField(tag, value)
                    else:
                        # this isn't a repeating group field, so just add it normally
                        decodedMsg.setField(tag, value)

                return (decodedMsg, remainingMsgFragment)
        except UnicodeDecodeError as why:
            logging.error("Failed to parse message %s" % (why, ))
            return (None, 0)
Example #2
0
    def sendOrder(self,
                  symbol,
                  side,
                  ordType,
                  quantity,
                  price=None,
                  connectionHandler=None):
        if not connectionHandler:
            connectionHandler = self.connectionHandler
        self.clOrdID = str(uuid.uuid4())
        codec = connectionHandler.codec
        msg = FIXMessage(codec.protocol.msgtype.NEWORDERSINGLE)
        if price and ordType == "limit":
            msg.setField(codec.protocol.fixtags.Price, price)
        msg.setField(codec.protocol.fixtags.OrderQty, quantity)
        msg.setField(codec.protocol.fixtags.OrdType,
                     self.orderTypeDict[ordType])
        msg.setField(codec.protocol.fixtags.TimeInForce, "1")
        msg.setField(codec.protocol.fixtags.Symbol, symbol)
        msg.setField(codec.protocol.fixtags.HandlInst, "1")
        msg.setField(codec.protocol.fixtags.Side, self.orderSideDict[side])
        msg.setField(codec.protocol.fixtags.ClOrdID, self.clOrdID)

        connectionHandler.sendMsg(msg)
        print("Send order at: " + str(self.current_datetime()))
Example #3
0
 def logon():
     msg = FIXMessage(msgtype.LOGON)
     msg.setField(fixtags.EncryptMethod, 0)
     msg.setField(fixtags.HeartBtInt, 30)
     return msg
Example #4
0
 def resend_request(beginSeqNo, endSeqNo = '0'):
     msg = FIXMessage(msgtype.RESENDREQUEST)
     msg.setField(fixtags.BeginSeqNo, str(beginSeqNo))
     msg.setField(fixtags.EndSeqNo, str(endSeqNo))
     return msg
Example #5
0
 def sequence_reset(respondingTo, isGapFill):
     msg = FIXMessage(msgtype.SEQUENCERESET)
     msg.setField(fixtags.GapFillFlag, 'Y' if isGapFill else 'N')
     msg.setField(fixtags.MsgSeqNum, respondingTo[fixtags.BeginSeqNo])
     return msg
    def _handleResendRequest(self, msg):
        protocol = self.codec.protocol
        responses = []

        beginSeqNo = msg[protocol.fixtags.BeginSeqNo]
        endSeqNo = msg[protocol.fixtags.EndSeqNo]
        if int(endSeqNo) == 0:
            endSeqNo = sys.maxsize
        logging.info("Received resent request from %s to %s", beginSeqNo,
                     endSeqNo)
        replayMsgs = self.engine.journaller.recoverMsgs(
            self.session, MessageDirection.OUTBOUND, beginSeqNo, endSeqNo)
        gapFillBegin = int(beginSeqNo)
        gapFillEnd = int(beginSeqNo)
        for replayMsg in replayMsgs:
            msgSeqNum = int(replayMsg[protocol.fixtags.MsgSeqNum])
            if replayMsg[protocol.fixtags.
                         MsgType] in protocol.msgtype.sessionMessageTypes:
                gapFillEnd = msgSeqNum + 1
            else:
                if self.engine.shouldResendMessage(self.session, replayMsg):
                    if gapFillBegin < gapFillEnd:
                        # we need to send a gap fill message
                        gapFillMsg = FIXMessage(protocol.msgtype.SEQUENCERESET)
                        gapFillMsg.setField(protocol.fixtags.GapFillFlag, 'Y')
                        gapFillMsg.setField(protocol.fixtags.MsgSeqNum,
                                            gapFillBegin)
                        gapFillMsg.setField(protocol.fixtags.NewSeqNo,
                                            str(gapFillEnd))
                        responses.append(gapFillMsg)

                    # and then resent the replayMsg
                    replayMsg.removeField(protocol.fixtags.BeginString)
                    replayMsg.removeField(protocol.fixtags.BodyLength)
                    replayMsg.removeField(protocol.fixtags.SendingTime)
                    replayMsg.removeField(protocol.fixtags.SenderCompID)
                    replayMsg.removeField(protocol.fixtags.TargetCompID)
                    replayMsg.removeField(protocol.fixtags.CheckSum)
                    replayMsg.setField(protocol.fixtags.PossDupFlag, "Y")
                    responses.append(replayMsg)

                    gapFillBegin = msgSeqNum + 1
                else:
                    gapFillEnd = msgSeqNum + 1
                    responses.append(replayMsg)

        if gapFillBegin < gapFillEnd:
            # we need to send a gap fill message
            gapFillMsg = FIXMessage(protocol.msgtype.SEQUENCERESET)
            gapFillMsg.setField(protocol.fixtags.GapFillFlag, 'Y')
            gapFillMsg.setField(protocol.fixtags.MsgSeqNum, gapFillBegin)
            gapFillMsg.setField(protocol.fixtags.NewSeqNo, str(gapFillEnd))
            responses.append(gapFillMsg)

        return responses
Example #7
0
    def sendOrder(self, connectionHandler, price, quantity, side):
        self.clOrdID = self.clOrdID + 1
        codec = connectionHandler.codec
        msg = FIXMessage(codec.protocol.msgtype.NEWORDERSINGLE)
        msg.setField(codec.protocol.fixtags.Price,
                     float(price))  #"%0.2f" % (random.random() * 2 + 10))
        msg.setField(codec.protocol.fixtags.OrderQty,
                     int(quantity))  # int(random.random() * 100))
        msg.setField(codec.protocol.fixtags.Symbol, "BTCUSD")
        msg.setField(codec.protocol.fixtags.SecurityID, "BTC")
        msg.setField(codec.protocol.fixtags.SecurityIDSource, "4")
        msg.setField(codec.protocol.fixtags.Account, "TEST")
        msg.setField(codec.protocol.fixtags.HandlInst, "1")
        msg.setField(codec.protocol.fixtags.ExDestination, "XLON")
        msg.setField(codec.protocol.fixtags.Side,
                     int(side))  #int(random.random() * 2) + 1)
        msg.setField(codec.protocol.fixtags.ClOrdID, str(self.clOrdID))
        msg.setField(codec.protocol.fixtags.Currency, "USD")

        connectionHandler.sendMsg(msg)
        side = Side(int(msg.getField(codec.protocol.fixtags.Side)))
        logging.debug("---> [%s] %s: %s %s %s@%s" %
                      (codec.protocol.msgtype.msgTypeToName(msg.msgType),
                       msg.getField(codec.protocol.fixtags.ClOrdID),
                       msg.getField(codec.protocol.fixtags.Symbol), side.name,
                       msg.getField(codec.protocol.fixtags.OrderQty),
                       msg.getField(codec.protocol.fixtags.Price)))