Ibpy: как получить данные, возвращенные из reqAccountSummary

Я использую ibapi от интерактивных брокеров, и я застрял в том, как вообще собирать возвращаемые данные. Например, согласно документам API, когда я запрашиваю reqAccountSummary() , метод доставил данные через accountSummary(). Но их пример только печатает данные. Я пытался захватить данные или присвоить их переменной, но нигде в их документах не показано, как это сделать. Я также искал в Google и нашел только register() и registerAll(), но это из ib.opt, которого нет в последнем рабочем пакете ibapi.

Вот мой код. Не могли бы вы показать мне, как изменить accountSummary() для сбора данных?

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()

person vt2424253    schedule 07.11.2017    source источник


Ответы (1)


В основной функции этого сделать нельзя, так как app.run слушает ответы от TWS. Как только вы правильно настроите все обратные вызовы, основная функция будет вечно зацикливаться в app.run.

Вы должны поместить свой код непосредственно в функцию accountSummary. Вот как работают такие программы, вы помещаете свою логику непосредственно в функции обратного вызова. Вы всегда можете назначить self.myTotalCashValue = value, чтобы сделать его доступным для других частей вашего класса или даже для другого потока.

-- OR --

Вы запускаете app.run в потоке и ждете возврата значения, например.

добавьте self._myTotalCashValue = value в accountSummary, импортируйте threading и time, а затем добавьте что-то вроде этого в main:

t = threading.Thread(target=app.run)
t.daemon = True
t.start()
while not hasattr(app,"_myTotalCashValue"):
    time.sleep(1)
print(app._myTotalCashValue)

Как обычно с потоками, вы должны быть немного осторожны с общей памятью между app и main.

person cronos    schedule 14.11.2017