Ejemplo n.º 1
0
 def historicalTicks(self, reqId, ticks, done):
     self._results[reqId] += [
         HistoricalTick(
             datetime.datetime.fromtimestamp(t.time, datetime.timezone.utc),
             t.price, t.size) for t in ticks if t.size
     ]
     if done:
         self._endReq(reqId)
Ejemplo n.º 2
0
    def _decode(self, fields):
        """
        Decode the fields of the single response and call the appropriate
        callback handler.
        """
        msgId = int(fields[0])

        # bypass the ibapi decoder for ticks for more efficiency
        if msgId == 1:
            if self._priceSizeTick:
                _, _, reqId, tickType, price, size, _ = fields
                self._priceSizeTick(int(reqId), int(tickType), float(price),
                                    int(size))
                return
        elif msgId == 2:
            _, _, reqId, tickType, size = fields
            self.wrapper.tickSize(int(reqId), int(tickType), int(size))
            return
        elif msgId == 12:
            _, _, reqId, position, operation, side, price, size = fields
            self.wrapper.updateMktDepth(int(reqId), int(position),
                                        int(operation), int(side),
                                        float(price), int(size))
            return
        elif msgId == 46:
            _, _, reqId, tickType, value = fields
            self.wrapper.tickString(int(reqId), int(tickType), value.decode())
            return
        elif msgId == 90:
            _, reqId, barCount, date, open_, close, high, low, \
                    average, volume = fields
            bar = BarData(date.decode(), float(open_), float(high), float(low),
                          float(close), float(volume), int(barCount),
                          float(average))
            self.wrapper.historicalDataUpdate(int(reqId), bar)
            return

        # snoop for nextValidId and managedAccounts response,
        # when both are in then the client is ready
        elif msgId == 9:
            _, _, validId = fields
            self._reqIdSeq = int(validId)
            if self._accounts:
                self._readyEvent.set()
        elif msgId == 15:
            _, _, accts = fields
            self._accounts = accts.decode().split(',')
            if self._reqIdSeq:
                self._readyEvent.set()

        # new features not yet in ibapi
        # https://interactivebrokers.github.io/tws-api/historical_time_and_sales.html
        elif msgId == 96:
            _, reqId, nTicks, *fields = fields
            ticks = []
            for _ in range(int(nTicks)):
                time, _, price, size, *fields = fields
                tick = HistoricalTick(int(time), float(price), int(size))
                ticks.append(tick)
            done = fields[0] == b'1'
            self.wrapper.historicalTicks(int(reqId), ticks, done)
            return
        elif msgId == 97:
            _, reqId, nTicks, *fields = fields
            ticks = []
            for _ in range(int(nTicks)):
                time, mask, priceBid, priceAsk, sizeBid, sizeAsk, \
                        *fields = fields
                tick = HistoricalTickBidAsk(int(time), int(mask),
                                            float(priceBid), float(priceAsk),
                                            int(sizeBid), int(sizeAsk))
                ticks.append(tick)
            done = fields[0] == b'1'
            self.wrapper.historicalTicksBidAsk(int(reqId), ticks, done)
            return
        elif msgId == 98:
            _, reqId, nTicks, *fields = fields
            ticks = []
            for _ in range(int(nTicks)):
                time, mask, price, size, exchange, \
                        specialConditions, *fields = fields
                tick = HistoricalTickLast(int(time), int(mask), float(price),
                                          int(size), exchange.decode(),
                                          specialConditions.decode())
                ticks.append(tick)
            done = fields[0] == b'1'
            self.wrapper.historicalTicksLast(int(reqId), ticks, done)
            return
        elif msgId == 99:
            _, reqId, tickType, time, *fields = fields
            if tickType in (1, 2):
                price, size, mask, exchange, specialConditions = fields
                mask = int(mask)
                attribs = TickAttrib(pastLimit=bool(mask & 1),
                                     unreported=bool(mask & 2))
                self.wrapper.tickByTickAllLast(int(reqId), int(tickType),
                                               int(time), float(price),
                                               int(size), attribs, exchange,
                                               specialConditions.decode())
            elif tickType == 3:
                bidPrice, askPrice, bidSize, askSize, mask = fields
                mask = int(mask)
                attribs = TickAttrib(bidPastLow=bool(mask & 1),
                                     askPastHigh=bool(mask & 2))
                self.wrapper.tickByTickBidAsk(int(reqId), int(time),
                                              float(bidPrice), float(askPrice),
                                              int(bidSize), int(askSize),
                                              attribs)
            elif tickType == 4:
                midPoint = fields[0]
                self.wrapper.tickByTickMidPoint(int(reqId), int(time),
                                                float(midPoint))
            return

        self.decoder.interpret(fields)
Ejemplo n.º 3
0
    def _decode(self, fields):
        """
        Decode the fields of the single response and call the appropriate
        callback handler.
        """
        msgId = int(fields[0])

        # bypass the abapi decoder for ticks for more efficiency
        if msgId == 1:
            if self._priceSizeTick:
                _, _, reqId, tickType, price, size, _ = fields
                self._priceSizeTick(int(reqId), int(tickType),
                        float(price), int(size))
                return
        elif msgId == 2:
            _, _, reqId, tickType, size = fields
            self.wrapper.tickSize(int(reqId), int(tickType), int(size))
            return
        elif msgId == 12:
            _, _, reqId, position, operation, side, price, size = fields
            self.wrapper.updateMktDepth(int(reqId), int(position),
                    int(operation), int(side), float(price), int(size))
            return
        elif msgId == 46:
            _, _, reqId, tickType, value = fields
            self.wrapper.tickString(int(reqId), int(tickType), value.decode())
            return
        elif msgId == 90:
            _, reqId, barCount, date, open_, close, high, low, \
                    average, volume = fields
            bar = BarData(date.decode(), float(open_), float(high),
                    float(low), float(close), float(volume),
                    int(barCount), float(average))
            self.wrapper.historicalDataUpdate(int(reqId), bar)
            return

        # snoop for nextValidId and managedAccounts response,
        # when both are in then the client is ready
        elif msgId == 9:
            _, _, validId = fields
            self._reqIdSeq = int(validId)
            if self._accounts:
                self._readyEvent.set()
        elif msgId == 15:
            _, _, accts = fields
            self._accounts = accts.decode().split(',')
            if self._reqIdSeq:
                self._readyEvent.set()

        # new features not yet in ibapi
        elif msgId == 96:
            reqId, nTicks, *fields = fields
            ticks = []
            for _ in range(nTicks):
                time, _, price, size, *fields = fields
                tick = HistoricalTick(int(time), float(price), int(size))
                ticks.append(tick)
            done = fields[0] == b'1'
            self.wrapper.historicalTicks(int(reqId), ticks, done)
            return
        elif msgId == 97:
            reqId, nTicks, *fields = fields
            ticks = []
            for _ in range(nTicks):
                time, mask, priceBid, priceAsk, sizeBid, sizeAsk, \
                        *fields = fields
                tick = HistoricalTickBidAsk(int(time), int(mask),
                        float(priceBid), float(priceAsk),
                        int(sizeBid), int(sizeAsk))
                ticks.append(tick)
            done = fields[0] == b'1'
            self.wrapper.historicalTicksBidAsk(int(reqId), ticks, done)
            return
        elif msgId == 98:
            reqId, nTicks, *fields = fields
            ticks = []
            for _ in range(int(nTicks)):
                time, mask, price, size, exchange, \
                        specialConditions, *fields = fields
                tick = HistoricalTickLast(int(time), int(mask),
                        float(price), int(size),
                        exchange.decode(), specialConditions.decode())
                ticks.append(tick)
            done = fields[0] == b'1'
            self.wrapper.historicalTicksLast(int(reqId), ticks, done)
            return

        self.decoder.interpret(fields)