Interactive Brokers just released a python version of their API. I am trying to get data.
I am using the 'examples' in 'Program.py', and just trying to get account values. I just want to know what the account liquidation value is, and get that into python. This is the documentation. And this is the code to create and send the request:
app = TestApp()
app.connect("127.0.0.1", 4001, clientId=0)
print("serverVersion:%s connectionTime:%s" % (app.serverVersion(),
app.twsConnectionTime()))
app.reqAccountSummary(9004, 'All', '$LEDGER')
I can use the IB Gateway, and see the request being sent, and the response coming back into IB Gateway. I cannot figure out how to get the response into Python. If I am reading the docs correctly, I see this:
Receiving
Summarised information is delivered via IBApi.EWrapper.accountSummary and IBApi.EWrapper.accountSummaryEnd
1 class TestWrapper(wrapper.EWrapper):
...
1 def accountSummary(self, reqId: int, account: str, tag: str, value: str,
2 currency: str):
3 super().accountSummary(reqId, account, tag, value, currency)
4 print("Acct Summary. ReqId:", reqId, "Acct:", account,
5 "Tag: ", tag, "Value:", value, "Currency:", currency)
6
...
1 def accountSummaryEnd(self, reqId: int):
2 super().accountSummaryEnd(reqId)
3 print("AccountSummaryEnd. Req Id: ", reqId)
What do I do with this? It seems like I call this function to get the values, but this function is requiring as an input the value I want returned! What am I missing!??!
Thanks for any help anyone can provide.
EDIT:
This is the 'callback' I think:
@iswrapper
# ! [accountsummary]
def accountSummary(self, reqId: int, account: str, tag: str, value: str,
currency: str):
super().accountSummary(reqId, account, tag, value, currency)
print("Acct Summary. ReqId:", reqId, "Acct:", account,
"Tag: ", tag, "Value:", value, "Currency:", currency)
And this is where I am confused. This seems to expect a value for the account ('value: str' in the declaration), which is exactly what I am asking it to produce. I cannot find where I would say somehting like the following:
myMonies = whateverTheHellGetsTheValue(reqID)
So, 'myMonies' would then hold the account value, and I can continue on my merry way.
I answered a very similar question here. https://stackoverflow.com/a/42868938/2855515
Here is a program where I subclass the EWrapper
and EClient
in the same class and use that for everything, requests and receiving callbacks.
You call EClient methods to request data and it is fed back through the EWrapper methods. Those are the ones with the @iswrapper
notation.
from ibapi import wrapper
from ibapi.client import EClient
from ibapi.utils import iswrapper #just for decorator
from ibapi.common import *
class TestApp(wrapper.EWrapper, EClient):
def __init__(self):
wrapper.EWrapper.__init__(self)
EClient.__init__(self, wrapper=self)
@iswrapper
def nextValidId(self, orderId:int):
print("setting nextValidOrderId: %d", orderId)
self.nextValidOrderId = orderId
# here is where you start using api
self.reqAccountSummary(9002, "All", "$LEDGER")
@iswrapper
def error(self, reqId:TickerId, errorCode:int, errorString:str):
print("Error. Id: " , reqId, " Code: " , errorCode , " Msg: " , errorString)
@iswrapper
def accountSummary(self, reqId:int, account:str, tag:str, value:str, currency:str):
print("Acct Summary. ReqId:" , reqId , "Acct:", account,
"Tag: ", tag, "Value:", value, "Currency:", currency)
@iswrapper
def accountSummaryEnd(self, reqId:int):
print("AccountSummaryEnd. Req Id: ", reqId)
# now we can disconnect
self.disconnect()
def main():
app = TestApp()
app.connect("127.0.0.1", 7497, clientId=123)
app.run()
if __name__ == "__main__":
main()