I have a python script that connects to an Interactive Brokers API and retrieves security contract information as below:
from ibapi.client import *
from ibapi.wrapper import *
import time
class TestApp(EClient, EWrapper):
def __init__(self):
EClient.__init__(self, self)
def contractDetails(self, reqId: int, contractDetails: ContractDetails):
print(f"contract details: {contractDetails}")
def contractDetailsEnd(self, reqId: int):
print("End of contractDetails")
self.disconnect()
def main():
try:
app = TestApp()
app.connect("127.0.0.1", 7496, 1000)
myContract = Contract()
# myContract.conId = "503837634"
myContract.symbol = "/ES"
myContract.exchange = "CME"
myContract.secType = "FUT"
myContract.currency = "USD"
myContract.localSymbol = 'ESZ3'
#myContract.primaryExchange = "ISLAND"
time.sleep(3)
app.reqContractDetails(1, myContract)
app.run()
except KeyboardInterrupt:
print('Session completed')
app.disconnect()
if __name__ == "__main__":
main()
In cases where I need to break the process (e.g., the program doesn't end naturally because a contract with specified details isn't found), I've set it up using a try/catch and KeyboardInterrupt
exception. This doesn't seem to get picked up so killing the process also kills the established connection and I'm forced to log in again manually.
I've considered using the signal
module but there doesn't seem to be a natural way to apply code snippets I've found to allow me to close the connection (app.disconnect()
) before exiting.
For example, I can implement a version of the linked to answer, as below, but there's no way to pass my app instance to be disconnected by the handler before exiting.
def handler(sig, frame):
print('Exception detected...session completed')
sys.exit(0)
def main():
app = TestApp()
app.connect("127.0.0.1", 7496, 1000)
myContract = Contract()
# myContract.conId = "503837634"
myContract.symbol = '/ES'
myContract.exchange = 'CME'
myContract.secType = "FUT"
myContract.currency = "USD"
myContract.localSymbol = 'ESZ3'
#myContract.primaryExchange = "ISLAND"
time.sleep(3)
app.reqContractDetails(1, myContract)
app.run()
signal.signal(signal.SIGINT, handler)
signal.pause()
app.disconnect()
if __name__ == "__main__":
main()
Can anyone shed some light on how to accomplish this?