Python API will print the first time only

Hi I have a Python script I copied from the tutorial. Just a simple script to print some ticker info.

It runs well the first time I run it and it prints out all the info it should.

However any time I try to run it again, it builds but nothing prints. I get no errors or anything. It's like it just ignore the print function.

I've noticed the first time I run it, in TWS, the API says "connected".

After that when I try running it again, "disconnected" flashes and then it just shows grey (neither "connected" nor "disconnected"). I don't know if this is part of the issue.

It does this even if I don't change anything, make a small change, or even try running a different script.

Here is the code snippet:

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.ticktype import TickTypeEnum
from ibapi.contract import Contract


class TestApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self,self)

def error(self, reqId, errorCode, errorString):
print("Error: ", reqId, " ", errorCode, " ", errorString)

def tickPrice(self, reqId, tickType, price, attrib):
print("TickPrice. TickerId:", reqId, "tickType:", TickTypeEnum.to_str(tickType),
"Price:", price, end=' ')

def tickSize(self, reqId, tickType, size):
print("Tick Size. TickerId:", reqId, "tickType:", TickTypeEnum.to_str(tickType),
"Size:", size)

def main():
app = TestApp()
app.connect('127.0.0.1', 7497, 0)

contract = Contract()
contract.symbol = 'AAPL'
contract.secType = 'STK'
contract.exchange = 'SMART'
contract.currency = 'USD'
contract.primaryExchange = 'NASDAQ'

app.reqMarketDataType(4)
app.reqMktData(1, contract, "", False, False, [])


if __name__ == "__main__":
main()
 
Confirm you're even receiving errors by supplying bad information. If you don't, the error function is not working. Otherwise, welcome to the three thread hell IB's Python API is. Good luck debugging it - it's a doozy.
 
My guess is the following: the first time you run it it connects to TWS via app.connect('127.0.0.1', 7497, 0) to session with ID zero. However, when you finish your program you don't disconnect. The next time you run it it tries to connect again to TWS using the same session ID (i.e. zero). It is likely that TWS remembered that this session is already in use. And it does not allow to use it again. Therefore the connection is refused.
If this guess is correct then there are two possible solutions: either use a unique ID for each time you call app.connect(). Or disconnect, using app.disconnect(0), before ending your program.
 
My guess is the following: the first time you run it it connects to TWS via app.connect('127.0.0.1', 7497, 0) to session with ID zero. However, when you finish your program you don't disconnect. The next time you run it it tries to connect again to TWS using the same session ID (i.e. zero). It is likely that TWS remembered that this session is already in use. And it does not allow to use it again. Therefore the connection is refused.
If this guess is correct then there are two possible solutions: either use a unique ID for each time you call app.connect(). Or disconnect, using app.disconnect(0), before ending your program.

Where do you put the app.disconnect(0)?
I've put it at the end of my "main()" function.

I get an error: "TypeError: disconnect() takes 1 positional argument but 2 were given"
If I just put "app.disconnect()" I get a different error:
"OSError: [WinError 10038] An operation was attempted on something that is not a socket"

Also now I can't get it to print once. It just builds with no errors. The API box pops up in TWS. So it's done something.

I also tested changing the client ID and it didn't make a difference.

It shows no open API connection in TWS before I run it.
And when i do it again just says client 0 'disconnected' for a bit, then goes away and is back to not showing any API connection.

I've copied the tutorial word for word. And it HAS worked at some point.

I'm not sure what is causing the issue now.

I've also tested the sample scripts and they DO seem to work.
 
Your main() should do four tasks:
(1) connect to TWS, using app.connect()
(2) subscribe to market data and print it on screen, using app.reqMktData()
using some sleep command you let this run for a while.
(3) end the subscription to the market data, using app.cancelMktData()
(4) disconnect from TWS, using app.disconnect()
only then can you end your main() in a decent manner.

In case you haven't found it yet, here is the available documentation as provided by IB: https://interactivebrokers.github.io/tws-api/index.html
 
Back
Top