Search code examples
pythonmultithreadinginteractive-brokers

Why is my reqMktData thread not running with IB TWS Python API?


I can't figure out why my streamData thread is not running, while the my con_thread is running fine. I know from using this piece of code in larger scripts that they do, in fact, receive the market data just fine from using this function and thread, so I can't understand why the con_thread being alive is True, while the stream_thread being alive is False. Any idea?

from ibapi.wrapper import EWrapper
from ibapi.client import EClient
from ibapi.contract import Contract
import threading
import time

class TradingApp(EWrapper, EClient):

    def __init__(self):
        EClient.__init__(self,self)

    def error(self, reqId, errorCode, errorString):
        print("Error. Id: ", reqId, " Code: ", errorCode, " Msg: ", errorString)

Underlying = Contract()
Underlying.localSymbol = "MESU2"
Underlying.secType = "FUT"
Underlying.currency = "USD"
Underlying.exchange = "GLOBEX"

def websocket_con():
    app.run()

def streamData():
    app.reqMarketDataType(2)
    app.reqMktData(3002, Underlying, "", False, False, [])

app = TradingApp()
app.connect("127.0.0.1", 7497, 3002)

time.sleep(1)

con_thread = threading.Thread(target=websocket_con, daemon=True)
con_thread.start()
time.sleep(1)

stream_thread = threading.Thread(target=streamData())
stream_thread.start()
time.sleep(1)

while True:
    print("conthread",con_thread.is_alive())
    print("streamthread",stream_thread.is_alive())
    time.sleep(1)

Solution

  • First of all please update how you are passing the function argument to the thread. No parenthesis after the function name. You are passing the function as a parameter not executing the function.

    stream_thread = threading.Thread(target=streamData)
    

    Secondly, why do you expect the stream_thread.is_alive() to return True? The function is complete and the websocket connection has been established and therefore it returns false. It will return True only till the streamData function is incomplete. If you want to test it, add a line time.sleep(10) within your streamData function and you will see it returning True for the stream_thread for 10 seconds.

    However, please note that your streaming is happening in the background although your code is not handling the streaming data. You will need an appropriate EWrapper function in your TradingApp. Something like below

    def tickPrice(self, reqId, tickType, price, attrib):
        super().tickPrice(reqId, tickType, price, attrib)
        print("TickPrice. TickerId:", reqId, "tickType:", tickType, "Price:", price)