如何在IB API中接收响应时发送请求?

时间:2017-06-05 01:49:19

标签: python api stream

我不太明白如何使用IB API Wrapper和客户端流。我知道我正在通过客户端流向IB服务器发送请求,并通过Wrapper流接收响应,但我希望能够为用户实现一个菜单,例如“按'p'打开位置等等“然后显示服务器响应和另一个操作的提示。

from ibapi import wrapper
from ibapi.client import EClient
from ibapi.utils import iswrapper

# types
from ibapi.common import *
from ibapi.contract import *


class TestClient(EClient):
    def __init__(self, wrapper):
        EClient.__init__(self, wrapper)


class TestWrapper(wrapper.EWrapper):
    def __init__(self):
        wrapper.EWrapper.__init__(self)


class TestApp(TestWrapper, TestClient):
    def __init__(self):
        TestWrapper.__init__(self)
        TestClient.__init__(self, wrapper=self)

    def position(self, account: str, contract: Contract, position: float,
                 avgCost: float):
        """This event returns real-time positions for all accounts in
        response to the reqPositions() method."""

        super().position(account, contract, position, avgCost)
        print("Position.", account, "Symbol:", contract.symbol, "SecType:",
              contract.secType, "Currency:", contract.currency,
              "Position:", position, "Avg cost:", avgCost)


def main():
    app = TestApp()
    usr_in = ''

    app.connect("127.0.0.1", 7497, clientId=0)
    print("serverVersion:%s connectionTime:%s" % (app.serverVersion(),
                                              app.twsConnectionTime()))

    while(usr_in != 'exit'):
         usr_in = input('What to do next?')
         if usr_in == 'p':
             app.reqPositions()

    app.run()

if __name__ == '__main__':
    main()

现在最终发生的是程序要求输入,但是在我退出循环之前不会显示服务器响应,之后它会显示响应。我知道我可以在position()函数中包含一些逻辑,但这是非常有限的,并且必须有一种更好的方式来与两个流进行交互。此外,将非常感谢指向任何有关流的主题的进一步读数的指针,如IB API中使用的那些。

1 个答案:

答案 0 :(得分:0)

我明白了!所有需要做的就是启动两个线程。一个是处理EClient的run()函数,另一个是运行app的循环函数。这是代码的样子:

from ibapi import wrapper
from ibapi.client import EClient
from ibapi.contract import *

import threading
import time


class TestApp(wrapper.EWrapper, EClient):
    def __init__(self):
        wrapper.EWrapper.__init__(self)
        EClient.__init__(self, wrapper=self)

        self.connect("127.0.0.1", 7497, clientId=0)
        print(f"serverVersion:{self.serverVersion()}
              connectionTime:{self.twsConnectionTime()}")

    def position(self, account: str, contract: Contract, position: float,
                 avgCost: float):
        """This event returns real-time positions for all accounts in
        response to the reqPositions() method."""

        super().position(account, contract, position, avgCost)
        print("Position.", account, "Symbol:", contract.symbol, "SecType:",
              contract.secType, "Currency:", contract.currency,
              "Position:", position, "Avg cost:", avgCost)

    def loop(self):
        while True:
            self.reqPositions()
            time.sleep(15)


def main():
    app = TestApp()

    reader_thread = threading.Thread(target=app.run)
    loop_thread = threading.Thread(target=app.loop)

    reader_thread.start()
    loop_thread.start()

if __name__ == '__main__':
    main()