问题
I'm using ibapi from interactive brokers and I got stuck on how to capture the returned data, generally. For example, according to api docs, when I request reqAccountSummary(), the method delivered the data via accountSummary(). But their example only print the data. I've tried capturing the data or assign it to a variable, but no where in their docs shows how to do this. I've also google search and only find register() and registerAll() but that is from ib.opt which isn't in the latest working ibapi package.
Here is my code. Could you show me how to modify accountSummary() to capture the data?
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.common import *
class TestApp(EWrapper,EClient):
def __init__(self):
EClient.__init__(self,self)
# request account data:
def my_reqAccountSummary1(self, reqId:int, groupName:str, tags:str):
self.reqAccountSummary(reqId, "All", "TotalCashValue")
# The received data is passed to 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)
return value #This is my attempt which doesn't work
def main():
app = TestApp()
app.connect("127.0.0.1",7497,clientId=0)
app.my_reqAccountSummary1(8003, "All", "TotalCashValue") #"This works, but the data is print to screen. I don't know how to assign the received TotalCashValue to a variable"
# myTotalCashValue=app.my_reqAccountSummary1(8003, "All", "TotalCashValue") #"My attempt doesn't work"
# more code to stop trading if myTotalCashValue is low
app.run()
if __name__=="__main__":
main()
回答1:
You cannot do this in the main function, since app.run
listens to responses from the TWS. Once you have set up all the callbacks as you correctly did, the main function will be looping forever in app.run
.
You have to put your code directly into the accountSummary
function. This is how these kind of programs work, you put your logic directly into
the callback functions. You can always assign self.myTotalCashValue = value
to make it available to other parts of your class, or even to another thread.
-- OR --
You run app.run in a thread and wait for the value to return, e.g.
add self._myTotalCashValue = value
to accountSummary, import threading
and time
and then add something like this in main:
t = threading.Thread(target=app.run)
t.daemon = True
t.start()
while not hasattr(app,"_myTotalCashValue"):
time.sleep(1)
print(app._myTotalCashValue)
As usual with threads, you have to be a bit careful with shared memory between app
and main
.
来源:https://stackoverflow.com/questions/47151737/ibpy-how-to-capture-data-returned-from-reqaccountsummary