erdewit / ib_insync

Python sync/async framework for Interactive Brokers API
BSD 2-Clause "Simplified" License
2.75k stars 723 forks source link

reqTickersAsync doesn't support custom ticker types #675

Closed eyalk11 closed 5 months ago

eyalk11 commented 6 months ago

Your reqTickersAsync doesn't support custom ticker types and always uses snapshot.

tickers=await self.reqTickersAsync('233,221,165',*contracts)

After non-trivial effort (understanding why tickers weren't closed) I rewritten it. I suggest to take it and combine. Won't open a PR.

    async def reqTickersAsync(
            self,genericTickList='', *contracts: Contract):
        s=self._ibsource.ibrem.ib
        futures = []
        tickers = []
        reqIds = []
        for contract in contracts:
            reqId = s.client.getReqId()
            reqIds.append(reqId)
            future = s.wrapper.startReq(reqId, contract)
            futures.append(future)
            ticker = s.wrapper.startTicker(reqId, contract, 15)
            tickers.append(ticker)
            def kk(reqId,ticker):
                logging.debug(('called', reqId))
                s.wrapper._endReq(reqId)

            ticker.updateEvent += partial(kk,reqId)
            s.client.reqMktData(
                reqId, contract,genericTickList=genericTickList,snapshot=False,regulatorySnapshot=False,mktDataOptions=[])

        ls=await asyncio.gather(*futures,return_exceptions=True)
        for w,id in enumerate(ls):
            if isinstance(w,Exception):
                logging.debug(('error',w,id))

        for ticker in tickers:
            s.wrapper.endTicker(ticker, 15)
        return tickers
erdewit commented 5 months ago

The point of ib.reqTickers is as a convenience for fetching possibly many snapshot tickers.

For continuous tickers there is ib.reqMktData. These have to be properly canceled when done with btw.