Python 如何在IB API中接收响应的同时发送请求?
我不太明白如何使用ibapi包装器和客户端流。我知道我正在通过客户端流向IB服务器发送请求,并且正在通过包装器流接收响应,但我希望能够为用户实现一个菜单,例如“按“p”打开位置等”,然后显示服务器响应并提示另一个操作Python 如何在IB API中接收响应的同时发送请求?,python,api,stream,Python,Api,Stream,我不太明白如何使用ibapi包装器和客户端流。我知道我正在通过客户端流向IB服务器发送请求,并且正在通过包装器流接收响应,但我希望能够为用户实现一个菜单,例如“按“p”打开位置等”,然后显示服务器响应并提示另一个操作 from ibapi import wrapper from ibapi.client import EClient from ibapi.utils import iswrapper # types from ibapi.common import * from ibapi.c
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中使用的流)主题的更多阅读资料,我们将不胜感激。我找到了!所有需要做的就是启动两个线程。一个将处理EClient的run()函数,另一个将运行应用程序的loop函数。下面是代码的样子:
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()
我知道了!所有需要做的就是启动两个线程。一个将处理EClient的run()函数,另一个将运行应用程序的loop函数。下面是代码的样子:
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()