Пример #1
0
 def execDetails(self, reqId, contract, execution):
     """
     This wrapper handles both live fills and responses to reqExecutions.
     """
     if execution.orderId == 2147483647:
         # bug in TWS: executions of manual orders have orderId=2**31 - 1
         execution.orderId = 0
     contract = self._getContract(contract)
     execId = execution.execId
     execution = Execution(**execution.__dict__)
     execution.time = util.parseIBDatetime(execution.time). \
             astimezone(datetime.timezone.utc)
     isLive = reqId not in self._futures
     time = self.lastTime if isLive else execution.time
     fill = Fill(contract, execution, CommissionReport(), time)
     if execId not in self.fills:
         # first time we see this execution so add it
         self.fills[execId] = fill
         key = self.orderKey(
                 execution.clientId, execution.orderId, execution.permId)
         trade = self.trades.get(key)
         if trade:
             trade.fills.append(fill)
             logEntry = TradeLogEntry(self.lastTime,
                     trade.orderStatus.status,
                     f'Fill {execution.shares}@{execution.price}')
             trade.log.append(logEntry)
             if isLive:
                 self.handleEvent('execDetailsEvent', trade, fill)
                 self._logger.info(f'execDetails: {fill}')
                 trade.fillEvent(trade, fill)
     if not isLive:
         self._results[reqId].append(fill)
Пример #2
0
 def execDetails(self, reqId, contract, execution):
     """
     This wrapper handles both live fills and responses to reqExecutions.
     """
     if execution.orderId == UNSET_INTEGER:
         # bug in TWS: executions of manual orders have unset value
         execution.orderId = 0
     key = self.orderKey(execution.clientId, execution.orderId,
                         execution.permId)
     trade = self.trades.get(key) or self.permId2Trade.get(execution.permId)
     if trade and contract == trade.contract:
         contract = trade.contract
     else:
         contract = Contract.create(**contract.dict())
     execId = execution.execId
     execution.time = util.parseIBDatetime(execution.time). \
         astimezone(datetime.timezone.utc)
     isLive = reqId not in self._futures
     time = self.lastTime if isLive else execution.time
     fill = Fill(contract, execution, CommissionReport(), time)
     if execId not in self.fills:
         # first time we see this execution so add it
         self.fills[execId] = fill
         if trade:
             trade.fills.append(fill)
             logEntry = TradeLogEntry(
                 time, trade.orderStatus.status,
                 f'Fill {execution.shares}@{execution.price}')
             trade.log.append(logEntry)
             if isLive:
                 self._logger.info(f'execDetails: {fill}')
                 self.ib.execDetailsEvent.emit(trade, fill)
                 trade.fillEvent(trade, fill)
     if not isLive:
         self._results[reqId].append(fill)
Пример #3
0
 def historicalDataUpdate(self, reqId, bar):
     bars = self.reqId2Bars[reqId]
     bar.date = util.parseIBDatetime(bar.date)
     if len(bars) == 0 or bar.date > bars[-1].date:
         bars.append(bar)
     else:
         bars[-1] = bar
Пример #4
0
 def historicalNews(
         self, reqId: int, time: str, providerCode: str,
         articleId: str, headline: str):
     dt = parseIBDatetime(time)
     dt = cast(datetime, dt)
     article = HistoricalNews(dt, providerCode, articleId, headline)
     self._results[reqId].append(article)
 def tickString(self, reqId: int, tickType: int, value: str):
     ticker = self.reqId2Ticker.get(reqId)
     if not ticker:
         return
     try:
         if tickType == 47:
             # https://interactivebrokers.github.io/tws-api/fundamental_ratios_tags.html
             d = dict(
                 t.split('=')  # type: ignore
                 for t in value.split(';') if t)  # type: ignore
             for k, v in d.items():
                 with suppress(ValueError):
                     if v == '-99999.99':
                         v = 'nan'
                     d[k] = float(v)
                     d[k] = int(v)
             ticker.fundamentalRatios = FundamentalRatios(**d)
         elif tickType in (48, 77):
             # RT Volume or RT Trade Volume string format:
             # price;size;ms since epoch;total volume;VWAP;single trade
             # example:
             # 701.28;1;1348075471534;67854;701.46918464;true
             priceStr, sizeStr, rtTime, volume, vwap, _ = value.split(';')
             if volume:
                 if tickType == 48:
                     ticker.rtVolume = int(volume)
                 elif tickType == 77:
                     ticker.rtTradeVolume = int(volume)
             if vwap:
                 ticker.vwap = float(vwap)
             if rtTime:
                 ticker.rtTime = datetime.fromtimestamp(
                     int(rtTime) / 1000, timezone.utc)
             if priceStr == '':
                 return
             price = float(priceStr)
             size = int(sizeStr)
             if price and size:
                 if ticker.prevLast != ticker.last:
                     ticker.prevLast = ticker.last
                     ticker.last = price
                 if ticker.prevLastSize != ticker.lastSize:
                     ticker.prevLastSize = ticker.lastSize
                     ticker.lastSize = size
                 tick = TickData(self.lastTime, tickType, price, size)
                 ticker.ticks.append(tick)
         elif tickType == 59:
             # Dividend tick:
             # https://interactivebrokers.github.io/tws-api/tick_types.html#ib_dividends
             # example value: '0.83,0.92,20130219,0.23'
             past12, next12, nextDate, nextAmount = value.split(',')
             ticker.dividends = Dividends(
                 float(past12) if past12 else None,
                 float(next12) if next12 else None,
                 parseIBDatetime(nextDate) if nextDate else None,
                 float(nextAmount) if nextAmount else None)
         self.pendingTickers.add(ticker)
     except ValueError:
         self._logger.error(f'tickString with tickType {tickType}: '
                            f'malformed value: {value!r}')
Пример #6
0
 def historicalDataUpdate(self, reqId, bar):
     bars = self.reqId2Bars[reqId]
     bar.date = util.parseIBDatetime(bar.date)
     if len(bars) == 0 or bar.date > bars[-1].date:
         bars.append(bar)
         self._handleEvent('barUpdate', bars, True)
     elif bars[-1] != bar:
         bars[-1] = bar
         self._handleEvent('barUpdate', bars, False)
Пример #7
0
def get_dte(dt):
    '''Gets days to expiry

    Arg: 
        (dt) as day in string format 'yyyymmdd'
    Returns:
        days to expiry as int'''

    return (util.parseIBDatetime(dt) - datetime.now().date()
            ).days + 1  # 1 day added to accommodate for US timezone
Пример #8
0
 def historicalDataUpdate(self, reqId, bar):
     bar = BarData(**bar.__dict__)
     bars = self.reqId2Bars.get(reqId)
     if not bars:
         return
     bar.date = util.parseIBDatetime(bar.date)
     if len(bars) == 0 or bar.date > bars[-1].date:
         bars.append(bar)
         self.handleEvent('barUpdate', bars, True)
     elif bars[-1] != bar:
         bars[-1] = bar
         self.handleEvent('barUpdate', bars, False)
Пример #9
0
 def historicalDataUpdate(self, reqId: int, bar: BarData):
     bars = self.reqId2Subscriber.get(reqId)
     if not bars:
         return
     bar.date = parseIBDatetime(bar.date)  # type: ignore
     hasNewBar = len(bars) == 0 or bar.date > bars[-1].date
     if hasNewBar:
         bars.append(bar)
     elif bars[-1] != bar:
         bars[-1] = bar
     else:
         return
     self.ib.barUpdateEvent.emit(bars, hasNewBar)
     bars.updateEvent.emit(bars, hasNewBar)
Пример #10
0
 def historicalDataUpdate(self, reqId, bar):
     bar = BarData(**bar.__dict__)
     bars = self.reqId2Subscriber.get(reqId)
     if not bars:
         return
     bar.date = util.parseIBDatetime(bar.date)
     hasNewBar = len(bars) == 0 or bar.date > bars[-1].date
     if hasNewBar:
         bars.append(bar)
     elif bars[-1] != bar:
         bars[-1] = bar
     else:
         return
     self._ib.barUpdateEvent.emit(bars, hasNewBar)
     bars.updateEvent.emit(bars, hasNewBar)
Пример #11
0
 def tickString(self, reqId, tickType, value):
     ticker = self.reqId2Ticker.get(reqId)
     if not ticker:
         return
     try:
         if tickType == 47:
             # https://interactivebrokers.github.io/tws-api/fundamental_ratios_tags.html
             ticker.fundamentalRatios = value
         elif tickType == 48:
             # RTVolume string format:
             # price;size;ms since epoch;total volume;VWAP;single trade
             # example:
             # 701.28;1;1348075471534;67854;701.46918464;true
             price, size, _, rtVolume, vwap, _ = value.split(';')
             if rtVolume:
                 ticker.rtVolume = int(rtVolume)
             if vwap:
                 ticker.vwap = float(vwap)
             if price == '':
                 return
             price = float(price)
             size = float(size)
             if price and size:
                 if ticker.prevLast != ticker.last:
                     ticker.prevLast = ticker.last
                     ticker.last = price
                 if ticker.prevLastSize != ticker.lastSize:
                     ticker.prevLastSize = ticker.lastSize
                     ticker.lastSize = size
                 tick = TickData(self.lastTime, tickType, price, size)
                 ticker.ticks.append(tick)
                 self.pendingTickers.add(ticker)
         elif tickType == 59:
             # Dividend tick:
             # https://interactivebrokers.github.io/tws-api/tick_types.html#ib_dividends
             # example value: '0.83,0.92,20130219,0.23'
             past12, next12, nextDate, nextAmount = value.split(',')
             ticker.dividends = Dividends(
                 float(past12) if past12 else None,
                 float(next12) if next12 else None,
                 util.parseIBDatetime(nextDate) if nextDate else None,
                 float(nextAmount) if nextAmount else None)
     except ValueError:
         self._logger.error(
             f'tickString with tickType {tickType}: '
             f'malformed value: {value!r}')
Пример #12
0
 def historicalData(self, reqId, bar):
     bar = BarData(**bar.__dict__)
     bar.date = util.parseIBDatetime(bar.date)
     self._results[reqId].append(bar)
Пример #13
0
 def historicalData(self, reqId: int, bar: BarData):
     bar.date = parseIBDatetime(bar.date)  # type: ignore
     self._results[reqId].append(bar)
Пример #14
0
 def headTimestamp(self, reqId, headTimestamp):
     dt = util.parseIBDatetime(headTimestamp)
     self._endReq(reqId, dt)
Пример #15
0
 def realtimeBar(self, reqId, time, open_, high, low, close, volume, wap,
                 count):
     dt = util.parseIBDatetime(time)
     bar = RealTimeBar(dt, -1, open_, high, low, close, volume, wap, count)
     self.reqId2Bars[reqId].append(bar)
Пример #16
0
async def get_dte(dt):
    return await (util.parseIBDatetime(dt) -
                  datetime.datetime.now().date()).days
Пример #17
0
        contracts = [c for cs in contracts for c in cs if c]

        for c in contracts:

            df_ohlc = ib.run(get_ohlc(ib, c))

            undPrice = ib.run(get_tick(ib, c))[0].marketPrice()

            chains = {c.symbol: ib.run(get_chain(ib, c))[0]}

            sek = {b for a in [list(product([k], m.expirations, m.strikes))
                               for k, m in chains.items()] for b in a}

            dfc = pd.DataFrame(list(sek), columns=[
                               'symbol', 'expiry', 'strike'])
            dfc = dfc.assign(dte=[(util.parseIBDatetime(
                dt)-datetime.datetime.now().date()).days for dt in dfc.expiry])

            # Limit to max and min dte
            dfc = dfc[dfc.dte <= data['common']['maxdte']]
            dfc = dfc[dfc.dte >= data['common']['mindte']]

            # integrate rise, fall and stdev
            dfc = dfc.join(dfc.dte.apply(
                lambda x: df_ohlc.iloc[x][['rise', 'fall', 'sd']]))

            # remove the calls and puts whose strike is in the threshold of st dev
            dfc['undPrice'] = undPrice
            dfc = dfc.assign(right=np.where(
                dfc.strike >= dfc.undPrice, 'C', 'P'))
            c_mask = (dfc.right == 'C') & (
                dfc.strike > dfc.undPrice + data['common']['callstdmult']*dfc.sd)
Пример #18
0
 def historicalData(self, reqId: int, bar: BarData):
     results = self._results.get(reqId)
     if results is not None:
         bar.date = parseIBDatetime(bar.date)  # type: ignore
         results.append(bar)
Пример #19
0
 def headTimestamp(self, reqId, headTimestamp):
     try:
         dt = util.parseIBDatetime(headTimestamp)
         self._endReq(reqId, dt)
     except ValueError as exc:
         self._endReq(reqId, exc, False)
Пример #20
0
def get_dte(dt):
    '''Gets days to expiry
    Arg: (dt) as day in string format 'yyyymmdd'
    Returns: days to expiry as int'''
    return (util.parseIBDatetime(dt) - 
            datetime.datetime.now().date()).days