I think I am going to move forward with IbPy, while its implementation is fairly messy I don't think there is an advantage to FIX at this point. It seems to me that most brokers have proprietary extensions to the protocol for sending/receiving messages that I would have to reimplement the messaging anyways if I ever moved to a different broker. Over the next week or two I am going to work on wrapping all the socket calls in a more pythonic syntax, and hopefully return the callback messages (for reconciling zipline with IB).
For example, here is a more concise working prototype I have for generating an order in IB
client = IBClient()
sleep(3)
ord_id = np.random.randint(200, 300)
client.order('GOOG', 100, ord_id)
I think in my final version I will just have blotter send the actual order object to my IB method so that it can access contract type (stock or future) and also determine the order type (MKT, LMT, STOP, STOPLIMIT, etc), and pass the id. Ultimately I think where I will need the most help, is in determining where, when and how to reconcile all of these values, and which ESocket methods ultimately request those values. Then I will create methods for all the requests, have my subclass of EWrapper catch that value and store it in a field that can be returned in the initial method call.
So conceptually, something like this:
class Wrapper(EWrapper):
account_value = None
finished_request = False
def updateAccountValue(self, key, value, currency, accountName):
self.account_value = (key, value, currency)
self.finished_request = True
class Listener(object):
def __init__(self,name=None):
def method(self,sender,event,msg=None):
print "[{0}] got event {1} with message {2}".format(
self.name,event,msg)
class IBClient(Listener):
def __init__(self, name=None):
self.host = 'localhost'
self.port = 7496
self.clientId = np.random.randint(0,1000)
self.wrapper = Wrapper()
self.connection = EClientSocket(self.wrapper)
self.wrapper.register(self.method, events='execution')
self.connect = self.connection.eConnect(self.host, self.port, self.clientId)
def wait_for_request(self):
while self.wrapper.finished_request is False:
sleep(.5)
def get_account(self, acct):
self.connection.reqAccountUpdates(True, acct)
wait_for_request()
return self.wrapper.account_value
client = IBClient()
account = client.get_account(acct# here)