Python IBAPI reqContractDetails won't return result when run second time
Asked Answered
B

1

4

I want to request contract details and it worked the first time I run the code, but when I press run again, it won't return anything. It will work if I quit TWS and pycharm and try again I am new to python and don't understand how it works overall, pls help.

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.common import *
from ibapi.contract import *
from ContractSamples import ContractSamples


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

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

    def contractDetails(self, reqId:int, contractDetails:ContractDetails):
        print("contractDetail: ", reqId, " ", contractDetails)


def main():
    app = TestApp()

    app.connect("127.0.0.1", 7496, 0)

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

    app.reqContractDetails(10, contract)

    app.run()


if __name__ == "__main__":
    main()

No error msg, just no result: "Process finished with exit code 0".

Biggin answered 5/7, 2019 at 3:1 Comment(0)
N
4

app.run() starts a thread to read from the socket. Your program never stops running so is always connected to TWS. Try clicking on the data menu button in TWS. It shows all your connections. You will see client 0 stays connected. Obviously closing pyCharm kills the program.

You also request the contract details before the program is ready. You should wait for nextValidId and then send the request. When the data has been recieved, then you can stop your program and it will free up the clientId for future connections. Here is how I would change your program.

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.common import *
from ibapi.contract import *
from ContractSamples import ContractSamples


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

    def nextValidId(self, orderId:int):
        print("id", orderId)
        contract = Contract()
        contract.symbol = "IBKR"
        contract.secType = "STK"
        contract.exchange = "SMART"
        contract.currency = "USD"
        contract.primaryExchange = "NASDAQ"

        self.reqContractDetails(10, contract)

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

    def contractDetails(self, reqId:int, contractDetails:ContractDetails):
        print("contractDetail: ", reqId, " ", contractDetails)

    def contractDetailsEnd(self, reqId:int):
        print("end, disconnecting")
        self.disconnect()

def main():
    app = TestApp()

    app.connect("127.0.0.1", 7496, 0)
    app.run()

if __name__ == "__main__":
    main()
Niki answered 6/7, 2019 at 20:57 Comment(1)
It works great, I can request again and again, thanks a lot. I still need sometime to figure out how it works exactly, thanks anyway.Biggin

© 2022 - 2024 — McMap. All rights reserved.