pythonpython-3.xinteractive-brokersibpy

IBpy Ewrapper methods don't work only EClientSocket


Hi I'm trying to use IBPy as per here: https://github.com/blampe/IbPy and it is reacting very weirdly. Methods calling upon the EClientSocket class returns data but any EClientSocket method calling to EWrapper or EWrapper methods returns None and/or has issues. I realize IB's API is asynchronous at its source in Java but I can't figure out where it's breaking. I have DDE/Socket connections enabled in TWS, and even a clientId(100) specified.

I am using the IB TWS demo from this link: https://www.interactivebrokers.com/en/index.php?f=553&twsdemo=1 and Python 3.4. My version of IBpy is installed using pip install ib-api.

Here is my code:

from ib.opt import ibConnection, Connection, message
from ib.ext.Contract import Contract
from ib.ext.EWrapper import EWrapper
from ib.ext.EClientSocket import EClientSocket
from ib.ext.ExecutionFilter import ExecutionFilter
from ib.ext.Order import Order
import time
from time import sleep

def reply_handler(msg):
print("Reply:", msg)

def create_contract(symbol, sec_type, exch, prim_exch, curr):
contract = Contract()
contract.m_symbol = symbol
contract.m_sec_type = sec_type
contract.m_exch = exch
contract.m_prim_exch = prim_exch
contract.m_curr = curr
return contract

if __name__ == "__main__":
tws_conn = ibConnection(host='localhost', port=7496, clientId=100)
tws_conn.connect()

tws_conn.registerAll(reply_handler)

contract = Contract()
contract.m_symbol = 'GE'
contract.m_exchange = 'SMART'
contract.m_localSymbol = 'GE'
contract.m_primaryExch = 'SMART'
contract.m_currency = 'USD'
contract.m_secType = 'STK'

#EClientSocket only methods
reply_handler(tws_conn.isConnected())
reply_handler(tws_conn.serverVersion())
reply_handler(tws_conn.TwsConnectionTime())

#EWrapper methods or calls to EWrapper methods
reply_handler(tws_conn.reqCurrentTime())
reply_handler(tws_conn.reqAccountUpdates(1, ''))
reply_handler(tws_conn.currentTime())
reply_handler(tws_conn.reqMktData(1, contract, '', False))
reply_handler(tws_conn.contractDetails(1, contract))

Here is the console output when the script is ran:

Server Version: 76

TWS Time at connection:20150529 23:29:54 PST

Reply: True

Reply: 76

Reply: 20150529 23:29:54 PST

Reply: None

Reply: None

Reply: currentTime time=None

Reply: None

Reply: None

Reply: contractDetails reqId=1, contractDetails=ib.ext.Contract.Contract object at 0x000000000287FB70

Reply: None

You can see that after the 3rd method the last EClientSocket call it stops working. I've looked into IB's and IBpy's documentation and this particular issue is not mentioned anywhere as well on Stackoverflow. Thanks for any help!


Solution

  • It's a bit confusing for you to wrap your calls in reply_handler(). It's registered with the tws_conn object to get all replies, that's all you need to do. Anything that's not a socket request like tws_conn.isConnected() just needs to be in a print(), which is all reply_handler does, but it makes it look like a reply from EReader - it's not.

    Also in tws_conn.contractDetails... you forgot req.

    from ib.opt import ibConnection, Connection, message
    from ib.ext.Contract import Contract
    from ib.ext.EWrapper import EWrapper
    from ib.ext.EClientSocket import EClientSocket
    
    def reply_handler(msg):
        print("Reply:", msg)
    
    tws_conn = ibConnection(host='localhost', port=7496, clientId=1)
    tws_conn.registerAll(reply_handler)
    tws_conn.connect()
    
    
    contract = Contract()
    contract.m_symbol = 'GE'
    contract.m_exchange = 'SMART'
    contract.m_currency = 'USD'
    contract.m_secType = 'STK'
    
    #EClientSocket only methods
    reply_handler(tws_conn.isConnected())
    reply_handler(tws_conn.serverVersion())
    reply_handler(tws_conn.TwsConnectionTime())
    
    #EWrapper methods or calls to EWrapper methods
    tws_conn.reqCurrentTime()
    tws_conn.reqContractDetails(1, contract)
    #tws_conn.disconnect()#don't forget at some point