2

I have created a demo account, and I am trying to receive delayed quotes with the following code, but it failed so far.

import re
import ib
from ib.ext.Contract import Contract
from ib.opt import ibConnection, message
from time import sleep

class Downloader(object):
    field4price = ''

    def __init__(self):
        self.tws = ibConnection('localhost', 7496, 9003)
        self.tws.register(self.tickPriceHandler, 'TickPrice')
        self.tws.connect()
        self._reqId = 5 # current request id

    def tickPriceHandler(self,msg):
        if msg.field == 4:
            self.field4price = msg.price
            #print '[debug]', msg

    def requestData(self,contract): 
        self.tws.reqMarketDataType(3)
        self.tws.reqMktData(self._reqId, contract, '', 1)
        self._reqId+=1

if __name__=='__main__':
    dl = Downloader()
    c = Contract()
    c.m_symbol = 'SPY'
    c.m_secType = 'STK'
    c.m_exchange = 'SMART'
    c.m_currency = 'USD'
    dl.requestData(c)
    sleep(3)
    print('Price - field 4: ', dl.field4price)

As I am working with a demo account, I have to work with delayed data, so that's why I added self.tws.reqMarketDataType(3) (see that link). My problem is that dl.field4price return an empty list for the SPY symbol which is impossible. How could I get the SPY stock price in considering the previous code? Did I make an error?

Jeremie
  • 405
  • 1
  • 7
  • 20
  • I don't know if ibpy works with delayed data. I don't know if delayed data works at all. I don't know if the demo account has delayed data. I do know that the ticktype is 68, not 4. The ibpy source code doesn't have this type in TickType.py (which you should be using instead of hardcoding 4). IB has a new python API as of 9.73 which may be of interest. – brian Mar 25 '18 at 21:49
  • @brian Yes, I knew they have a python API. Maybe you should show me a similar code with the IB API. – Jeremie Mar 26 '18 at 02:58
  • I was just looking at the docs and it says `Note: TWS Build 962 or higher is required and API version 9.72.18 or higher is suggested.` I would need to update TWS to test this, so not now. Just add the delayed line to this https://stackoverflow.com/a/42868938/2855515 – brian Mar 26 '18 at 16:31

2 Answers2

3

I don't know if you figured it out yet, but IB has forced an upgrade so I'm using ver 963 now. I just added what I suggested and added the delayed request to an old sample. I used Canadian stocks since I'm not subscribed but maybe that doesn't even matter.

from ibapi import wrapper
from ibapi.client import EClient
from ibapi.utils import iswrapper #just for decorator
from ibapi.common import *
from ibapi.contract import *
from ibapi.ticktype import *

class TestApp(wrapper.EWrapper, EClient):
    def __init__(self):
        wrapper.EWrapper.__init__(self)
        EClient.__init__(self, wrapper=self)
        self.count = 0

    @iswrapper
    def nextValidId(self, orderId:int):
        print("nextValidOrderId:", orderId)
        self.nextValidOrderId = orderId

        #here is where you start using api
        contract = Contract()
        contract.symbol = "RY"
        contract.secType = "STK"
        contract.currency = "CAD"
        contract.exchange = "SMART"
        self.reqMarketDataType(3)
        self.reqMktData(1101, contract, "", False, None)

    @iswrapper
    def error(self, reqId:TickerId, errorCode:int, errorString:str):
        print("Error. Id: " , reqId, " Code: " , errorCode , " Msg: " , errorString)

    @iswrapper
    def tickPrice(self, reqId: TickerId , tickType: TickType, price: float,
                  attrib:TickAttrib):
        print("Tick Price. Ticker Id:", reqId,
              "tickType:", TickTypeEnum.to_str(tickType),
              "Price:", price)
        #just disconnect after a bit
        self.count += 1
        if self.count > 10 : self.disconnect()

#I use jupyter but here is where you use if __name__ == __main__:
app = TestApp()
app.connect("127.0.0.1", 7497, clientId=123)
print("serverVersion:%s connectionTime:%s" % app.serverVersion(),app.twsConnectionTime()))
app.run()

Here is part of the output, notice you can use ib's enum type to get the name of the tick type.

Error. Id: 1101 Code: 10167 Msg: Requested market data is not subscribed. Displaying delayed market data... Tick Price. Ticker Id: 1101 tickType: DELAYED_BID Price: 97.02 Tick Price. Ticker Id: 1101 tickType: DELAYED_ASK Price: 97.02 Tick Price. Ticker Id: 1101 tickType: DELAYED_LAST Price: 0.0

It's 9:40 am as I type this so the market is open but It's not 15 minutes delayed yet. The DELAYED_LAST of 0.0 would need to be filtered out. I don't think I've ever seen a real time last of 0.0, so beware.

I waited to 9:45 and I received

Tick Price. Ticker Id: 1101 tickType: DELAYED_LAST Price: 97.63

right on time.

brian
  • 10,619
  • 4
  • 21
  • 79
0

as my development work was mostly outside RTH, the type 4 (Last price) wasn't always available. thus, i tried type 9 (Close price) as an alternative. the whole information may be seen here

alex

alex
  • 651
  • 1
  • 9
  • 11