コード例 #1
0
ファイル: reader.py プロジェクト: fabiorodp/f1_trading
    def run(self):
        try:
            logger.debug("EReader thread started")
            buf = b""
            while self.conn.isConnected():

                data = self.conn.recvMsg()
                logger.debug("reader loop, recvd size %d", len(data))
                buf += data

                while len(buf) > 0:
                    (size, msg, buf) = comm.read_msg(buf)
                    #logger.debug("resp %s", buf.decode('ascii'))
                    logger.debug("size:%d msg.size:%d msg:|%s| buf:%s|", size,
                                 len(msg), buf, "|")

                    if msg:
                        self.msg_queue.put(msg)
                    else:
                        logger.debug("more incoming packet(s) are needed ")
                        break

            logger.debug("EReader thread finished")
        except:
            logger.exception('unhandled exception in EReader thread')
コード例 #2
0
    def run(self):
        while self.conn.isConnected():
        
            buf = self.prevBuf + self.conn.recvMsg()
            logging.debug("reader loop, prevBuf.size: %d recvd size: %d buf %s",
                len(self.prevBuf), len(buf), buf)
           
            while len(buf) > 0:
                (size, msg, buf) = comm.read_msg(buf)
                #logging.debug("resp %s", buf.decode('ascii'))
                logging.debug("size:%d msg.size:%d msg:|%s| buf:%s|", size,
                    len(msg), buf, "|")

                if len(msg) == size:
                    self.msg_queue.put(msg)
                    self.prevBuf = b""
                elif len(msg) < size:
                    logging.debug("more incoming packet(s) are needed ")
                    self.prevBuf = buf
                    break
                else:
                    logging.error("recvd bigger msg (%d) than expected (%d)", 
                        len(msg), size)

        logging.debug("EReader thread finished")
コード例 #3
0
    def test_read_msg(self):
        text = "ABCD"
        msg = comm.make_msg(text)

        (size, text2, rest) = comm.read_msg(msg)

        self.assertEqual(size, len(text), "msg size not good")
        self.assertEqual(text2.decode(), text, "msg payload not good")
        self.assertEqual(len(rest), 0, "there should be no remainder msg")
コード例 #4
0
    def test_readFields(self):
        text1 = "ABCD"
        text2 = "123"

        msg = comm.make_msg(comm.make_field(text1) + comm.make_field(text2))

        (size, text, rest) = comm.read_msg(msg)
        fields = comm.read_fields(text)

        self.assertEqual(len(fields), 2, "incorrect number of fields")
        self.assertEqual(fields[0].decode(), text1)
        self.assertEqual(fields[1].decode(), text2)
コード例 #5
0
    def run(self):
        try:
            buf = b""
            while self.conn.isConnected():

                try:
                    data = self.conn.recvMsg()
                    logger.debug("reader loop, recvd size %d", len(data))
                    buf += data

                except OSError as err:
                    #If connection is disconnected, Windows will generate error 10038
                    if err.errno == 10038:

                        #Wait up to 1 second for disconnect confirmation
                        waitUntil = time.time() + 1
                        while time.time() < waitUntil:
                            if not self.conn.isConnected():
                                break
                            time.sleep(.1)

                        if not self.conn.isConnected():
                            logger.debug("Ignoring OSError: {0}".format(err))
                            break

                    #Disconnect wasn't received or error != 10038
                    raise

                while len(buf) > 0:
                    (size, msg, buf) = comm.read_msg(buf)
                    #logger.debug("resp %s", buf.decode('ascii'))
                    logger.debug("size:%d msg.size:%d msg:|%s| buf:%s|", size,
                                 len(msg), buf, "|")

                    if msg:
                        self.msg_queue.put(msg)
                    else:
                        logger.debug("more incoming packet(s) are needed ")
                        break

            logger.debug("EReader thread finished")
        except:
            logger.exception('unhandled exception in EReader thread')
コード例 #6
0
    def send_msg(self, msg):
        """Mock send to ib by interpreting and placing on receive queue.

        Args:
            msg: message to be sent (i.e., interpreted and queued)

        """
        logger.debug('entered with message %s', msg)
        (size, msg2, buf) = read_msg(msg)
        logger.debug('size, msg, buf: %d, %s, %s ', size, msg2, buf)
        fields = read_fields(msg2)
        logger.debug('fields: %s', fields)

        recv_msg = b''

        #######################################################################
        # get version and connect time (special case - not decode able)
        #######################################################################
        if msg == b'API\x00\x00\x00\x00\tv100..157':
            current_dt = datetime.now(
                tz=timezone(offset=timedelta(hours=5))).\
                strftime('%Y%m%d %H:%M:%S')

            # recv_msg = b'\x00\x00\x00\x1a157\x0020210301 23:43:23 EST\x00'
            recv_msg = b'\x00\x00\x00\x1a157\x00' \
                       + current_dt.encode('utf-8') + b' EST\x00'

        #######################################################################
        # reqId (get next valid requestID)
        # b'\x00\x00\x00\x0871\x002\x000\x00\x00'
        #######################################################################
        elif int(fields[0]) == OUT.START_API:
            logger.info('startAPI detected')
            # recv_msg = b'\x00\x00\x00\x069\x001\x001\x00'
            if self.reqId_timeout:  # if testing timeout case
                recv_msg = make_msg('0')  # simulate timeout
            else:  # build the normal next valid id message
                recv_msg = make_msg(
                    make_field(IN.NEXT_VALID_ID) + make_field('1') +
                    make_field('1'))
            logger.debug('recv_msg: %s', recv_msg)
        #######################################################################
        # Handle special test cases for request disconnect and timeout
        #######################################################################
        elif self.simulate_request_disconnect:  # if testing timeout case
            time.sleep(2)  # allow some time for request to get into wait loop
            recv_msg = b''  # simulate disconnect
        elif self.simulate_request_timeout:
            recv_msg = make_msg('0')  # simulate timeout
        #######################################################################
        # reqMatchingSymbols
        #######################################################################
        elif int(fields[0]) == OUT.REQ_MATCHING_SYMBOLS:
            logger.info('reqMatchingSymbols detected')
            reqId = int(fields[1])
            pattern = fields[2].decode(errors='backslashreplace')
            logger.debug('pattern: %s', pattern)

            # construct start of receive message for wrapper
            build_msg = make_field(IN.SYMBOL_SAMPLES) + make_field(reqId)

            # find pattern matches in mock contract descriptions
            symbol_starts_with_pattern = \
                self.contract_descriptions['symbol'].map(
                    lambda symbol: symbol.startswith(pattern))
            match_descs = \
                self.contract_descriptions[symbol_starts_with_pattern]

            # match_descs = self.contract_descriptions.loc[
            #     self.contract_descriptions['symbol'].str.
            #     startswith(pattern)]

            # limit the number found as ib does
            num_found = min(self.MAX_CONTRACT_DESCS_RETURNED,
                            match_descs.shape[0])

            # add the number of descriptions to the receive message
            build_msg = build_msg + make_field(num_found)

            for i in range(num_found):
                build_msg = build_msg \
                    + make_field(match_descs.iloc[i].conId) \
                    + make_field(match_descs.iloc[i].symbol) \
                    + make_field(match_descs.iloc[i].secType) \
                    + make_field(match_descs.iloc[i].primaryExchange) \
                    + make_field(match_descs.iloc[i].currency) \
                    + make_field(len(match_descs.iloc[i].derivativeSecTypes))

                for dvt in match_descs.iloc[i].derivativeSecTypes:
                    build_msg = build_msg + make_field(dvt)

            recv_msg = make_msg(build_msg)

        #######################################################################
        # reqContractDetails
        #######################################################################
        elif int(fields[0]) == OUT.REQ_CONTRACT_DATA:
            logger.info('reqContractDetails detected')
            version = int(fields[1])
            reqId = int(fields[2])
            conId = int(fields[3])

            # construct start of receive message for wrapper
            start_msg = make_field(IN.CONTRACT_DATA) \
                + make_field(version) \
                + make_field(reqId)

            # find pattern matches in mock contract descriptions
            # fow now, just conId
            match_descs = self.contract_descriptions.loc[
                self.contract_descriptions['conId'] == conId]

            for i in range(len(match_descs)):
                build_msg = start_msg \
                    + make_field(match_descs.iloc[i].symbol) \
                    + make_field(match_descs.iloc[i].secType) \
                    + make_field(match_descs.iloc[i].
                                 lastTradeDateOrContractMonth) \
                    + make_field(match_descs.iloc[i].strike) \
                    + make_field(match_descs.iloc[i].right) \
                    + make_field(match_descs.iloc[i].exchange) \
                    + make_field(match_descs.iloc[i].currency) \
                    + make_field(match_descs.iloc[i].localSymbol) \
                    + make_field(match_descs.iloc[i].marketName) \
                    + make_field(match_descs.iloc[i].tradingClass) \
                    + make_field(match_descs.iloc[i].conId) \
                    + make_field(match_descs.iloc[i].minTick) \
                    + make_field(match_descs.iloc[i].mdSizeMultiplier) \
                    + make_field(match_descs.iloc[i].multiplier) \
                    + make_field(match_descs.iloc[i].orderTypes) \
                    + make_field(match_descs.iloc[i].validExchanges) \
                    + make_field(match_descs.iloc[i].priceMagnifier) \
                    + make_field(match_descs.iloc[i].underConId) \
                    + make_field(match_descs.iloc[i].longName) \
                    + make_field(match_descs.iloc[i].primaryExchange) \
                    + make_field(match_descs.iloc[i].contractMonth) \
                    + make_field(match_descs.iloc[i].industry) \
                    + make_field(match_descs.iloc[i].category) \
                    + make_field(match_descs.iloc[i].subcategory) \
                    + make_field(match_descs.iloc[i].timeZoneId) \
                    + make_field(match_descs.iloc[i].tradingHours) \
                    + make_field(match_descs.iloc[i].liquidHours) \
                    + make_field(match_descs.iloc[i].evRule) \
                    + make_field(match_descs.iloc[i].evMultiplier) \
                    + make_field(match_descs.iloc[i].secIdListCount)

                for tv in match_descs.iloc[i].secIdList:
                    build_msg += make_field(tv)

                build_msg += make_field(match_descs.iloc[i].aggGroup) \
                    + make_field(match_descs.iloc[i].underSymbol) \
                    + make_field(match_descs.iloc[i].underSecType) \
                    + make_field(match_descs.iloc[i].marketRuleIds) \
                    + make_field(match_descs.iloc[i].realExpirationDate) \
                    + make_field(match_descs.iloc[i].stockType)

                recv_msg = make_msg(build_msg)
                self.msg_rcv_q.put(recv_msg, timeout=5)

            build_msg = make_field(IN.CONTRACT_DATA_END) \
                + make_field(version) \
                + make_field(reqId)
            recv_msg = make_msg(build_msg)

        #######################################################################
        # queue the message to be received
        #######################################################################
        self.msg_rcv_q.put(recv_msg, timeout=5)