Ejemplo n.º 1
0
 def get_message(self):
     """
     亲测可用
     用来抓信息的
     """
     time.sleep(2)
     while not self.msg_queue.empty():
         text = self.msg_queue.get(block=True, timeout=0.2)
         # print("貌似下面会接着自动调用nextValidId函数")
         # print(f"报文:{text}")
         fields = comm.read_fields(text)
         self.decoder.interpret(fields)
Ejemplo n.º 2
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)
Ejemplo n.º 3
0
 def checkQueue(self):
     try:
         print("*********Checking Queue***************")
         text = self.msg_queue.get(block=True, timeout=0.2)
     except queue.Empty:
         print("-------------Queue is empty---------------")
         logging.debug("queue.get: empty")
     else:
         print("+++++++++++Reading Data++++++++++++++++++")
         fields = comm.read_fields(text)
         logging.debug("fields %s", fields)
         #print(datetime.now(), 'CALLING INTERPRETER TOO')
         self.decoder.interpret(fields)
Ejemplo n.º 4
0
    def run(self):
        if not self.done and self.isConnected():
            try:
                text = self.msg_queue.get(block=True, timeout=0.2)

                if len(text) > MAX_MSG_LEN:
                    errorMsg = "%s:%d:%s" % (BAD_LENGTH.msg(), len(text), text)
                    self.wrapper.error(NO_VALID_ID, BAD_LENGTH.code(),
                                       errorMsg)
                    self.disconnect()
                    # break

                fields = comm.read_fields(text)
                self.decoder.interpret(fields)
            except Empty:
                pass
Ejemplo n.º 5
0
    def run(self):
        """
        This is the function that has the message loop.

        Extended copy of the EClient run()
        + onLoopIteration() hook
        + onIdle() hook
        """
        try:
            while not self.done and (self.isConnected()
                                     or not self.msg_queue.empty()):
                try:
                    try:
                        # Hook to process messages/events from other sources.
                        self.onLoopIteration()
                        text = self.msg_queue.get(block=True, timeout=0.2)
                        if len(text) > MAX_MSG_LEN:
                            self.wrapper.error(
                                NO_VALID_ID, BAD_LENGTH.code(), "%s:%d:%s" %
                                (BAD_LENGTH.msg(), len(text), text))
                            self.disconnect()
                            break
                    except queue.Empty:
                        # Hook to process something while no messages are
                        # comming from the TWS.
                        # self.onIdle()
                        logging.debug("queue.get: empty")
                    else:
                        fields = comm.read_fields(text)
                        logging.debug("fields %s", fields)
                        self.decoder.interpret(fields)
                except (KeyboardInterrupt, SystemExit):
                    logging.info("detected KeyboardInterrupt, SystemExit")
                    self.keyboardInterrupt()
                    self.keyboardInterruptHard()
                except BadMessage:
                    logging.info("BadMessage")
                    self.conn.disconnect()
                except Exception:
                    logging.error(traceback.format_exc())
                logging.debug("conn:%d queue.sz:%d", self.isConnected(),
                              self.msg_queue.qsize())
        finally:
            self.disconnect()
Ejemplo n.º 6
0
    def run(self):
        """
        Reimplement the original run message loop of eclient.

        Remove all unnecessary try...catch... and allow exceptions to interrupt loop.
        """
        while not self.done and self.isConnected():
            try:
                text = self.msg_queue.get(block=True, timeout=0.2)

                if len(text) > MAX_MSG_LEN:
                    errorMsg = "%s:%d:%s" % (BAD_LENGTH.msg(), len(text), text)
                    self.wrapper.error(NO_VALID_ID, BAD_LENGTH.code(),
                                       errorMsg)
                    self.disconnect()
                    break

                fields = comm.read_fields(text)
                self.decoder.interpret(fields)
            except Empty:
                pass
Ejemplo n.º 7
0
    def run(self):
        """
        Reimplement the original run message loop of eclient.

        Remove all unnecessary try...catch... and allow exceptions to interrupt loop.
        """
        while not self.done and self.isConnected():
            try:
                text = self.msg_queue.get(block=True, timeout=0.2)

                if len(text) > MAX_MSG_LEN:
                    errorMsg = "%s:%d:%s" % (BAD_LENGTH.msg(), len(text), text)
                    self.wrapper.error(
                        NO_VALID_ID, BAD_LENGTH.code(), errorMsg
                    )
                    self.disconnect()
                    break

                fields = comm.read_fields(text)
                self.decoder.interpret(fields)
            except Empty:
                pass
Ejemplo n.º 8
0
    def runnable(self, func):
        """This is the function that has the message loop."""

        try:
            while not self.done and (self.conn.isConnected()
                                     or not self.msg_queue.empty()):
                try:
                    try:
                        text = self.msg_queue.get(block=True, timeout=0.2)
                        if len(text) > MAX_MSG_LEN:
                            self.wrapper.error(
                                NO_VALID_ID, BAD_LENGTH.code(), "%s:%d:%s" %
                                (BAD_LENGTH.msg(), len(text), text))
                            self.disconnect()
                            break
                    except queue.Empty:
                        if datetime.datetime.utcnow(
                        ) - self.lastStamp > datetime.timedelta(seconds=30):
                            func()
                            self.lastStamp = datetime.datetime.utcnow()
                        logging.debug("queue.get: empty")
                    else:
                        fields = comm.read_fields(text)
                        logging.debug("fields %s", fields)
                        self.decoder.interpret(fields)
                except (KeyboardInterrupt, SystemExit):
                    logging.info("detected KeyboardInterrupt, SystemExit")
                    self.keyboardInterrupt()
                    self.keyboardInterruptHard()
                except BadMessage:
                    logging.info("BadMessage")
                    self.conn.disconnect()

                logging.debug("conn:%d queue.sz:%d", self.conn.isConnected(),
                              self.msg_queue.qsize())
        finally:
            self.disconnect()
Ejemplo n.º 9
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)
Ejemplo n.º 10
0
 def getMessage(self, wait=3):
     time.sleep(wait)
     while not self.msg_queue.empty():
         text = self.msg_queue.get(block=True, timeout=0.2)
         fields = comm.read_fields(text)
         self.decoder.interpret(fields)