我用Python编写并使用IB TWS API编写的交易应用程序是多线程的,我希望一劳永逸地解决所有损坏的打印和重复订单IB问题,这两个问题都可以在多个线程同时运行时发生。
为了解决这个问题,我编写了一个简单的脚本,除了为解决这个问题提供支持之外,没有其他任何东西可以达到目标。我希望看到更有经验的人如何实现队列,从而使脚本完成两件事:
我知道我需要使用队列,但我刚刚开始阅读这个主题,而且由于IB TWS API相当具体,我不知道如何实现。谢谢。
from ibapi.wrapper import EWrapper
from ibapi.client import EClient
from ibapi.order import Order
from ibapi.contract import Contract
import threading
import time
buyOrder1Id = 0
buyOrder2Id = 0
buyOrder3Id = 0
buyOrder4Id = 0
buyOrder5Id = 0
buyOrder6Id = 0
buyOrder7Id = 0
buyOrder8Id = 0
buyOrder9Id = 0
buyOrder10Id = 0
class TradingApp(EWrapper, EClient):
def __init__(self):
self.BidPrice = 0
self.AskPrice = 0
self.LastPrice = 0
EClient.__init__(self,self)
def error(self, reqId, errorCode, errorString):
print("Error. Id: ", reqId, " Code: ", errorCode, " Msg: ", errorString)
def nextValidId(self, orderId):
super().nextValidId(orderId)
self.nextValidOrderId = orderId
def websocket_con():
app.run()
Underlying = Contract()
Underlying.localSymbol = "ESU2"
Underlying.secType = "FUT"
Underlying.currency = "USD"
Underlying.exchange = "GLOBEX"
BuyOrder1 = Order()
BuyOrder1.action = "BUY"
BuyOrder1.totalQuantity = 1
BuyOrder1.orderType = "MKT"
BuyOrder1.account = "DU2312534"
BuyOrder1.tif = "GTC"
app = TradingApp()
app.connect("127.0.0.1", 7497, 2000)
time.sleep(1)
# starting a separate daemon thread to execute the websocket connection
con_thread = threading.Thread(target=websocket_con, daemon=True)
con_thread.start()
time.sleep(1)# some latency added to ensure that the connection is established
def Level1():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder1Id = app.nextValidOrderId
print("buyOrder1Id: ",buyOrder1Id)
app.placeOrder(buyOrder1Id,Underlying,BuyOrder1)
time.sleep(3)
def Level2():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder2Id = app.nextValidOrderId
print("buyOrder2Id: ",buyOrder2Id)
app.placeOrder(buyOrder2Id,Underlying,BuyOrder1)
time.sleep(3)
def Level3():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder3Id = app.nextValidOrderId
print("buyOrder3Id: ",buyOrder3Id)
app.placeOrder(buyOrder3Id,Underlying,BuyOrder1)
time.sleep(3)
def Level4():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder4Id = app.nextValidOrderId
print("buyOrder4Id: ",buyOrder4Id)
app.placeOrder(buyOrder4Id,Underlying,BuyOrder1)
time.sleep(3)
def Level5():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder5Id = app.nextValidOrderId
print("buyOrder5Id: ",buyOrder5Id)
app.placeOrder(buyOrder5Id,Underlying,BuyOrder1)
time.sleep(3)
def Level6():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder6Id = app.nextValidOrderId
print("buyOrder6Id: ",buyOrder6Id)
app.placeOrder(buyOrder6Id,Underlying,BuyOrder1)
time.sleep(3)
def Level7():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder7Id = app.nextValidOrderId
print("buyOrder7Id: ",buyOrder7Id)
app.placeOrder(buyOrder7Id,Underlying,BuyOrder1)
time.sleep(3)
def Level8():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder8Id = app.nextValidOrderId
print("buyOrder8Id: ",buyOrder8Id)
app.placeOrder(buyOrder8Id,Underlying,BuyOrder1)
time.sleep(3)
def Level9():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder9Id = app.nextValidOrderId
print("buyOrder9Id: ",buyOrder9Id)
app.placeOrder(buyOrder9Id,Underlying,BuyOrder1)
time.sleep(3)
def Level10():
while True:
app.reqIds(1)
time.sleep(1)
buyOrder10Id = app.nextValidOrderId
print("buyOrder10Id: ",buyOrder10Id)
app.placeOrder(buyOrder10Id,Underlying,BuyOrder1)
time.sleep(3)
level1_thread = threading.Thread(target=Level1)
level1_thread.start()
level2_thread = threading.Thread(target=Level2)
level2_thread.start()
time.sleep(1)
level3_thread = threading.Thread(target=Level3)
level3_thread.start()
time.sleep(1)
level4_thread = threading.Thread(target=Level4)
level4_thread.start()
time.sleep(1)
level5_thread = threading.Thread(target=Level5)
level5_thread.start()
time.sleep(1)
level6_thread = threading.Thread(target=Level6)
level6_thread.start()
time.sleep(1)
level7_thread = threading.Thread(target=Level7)
level7_thread.start()
time.sleep(1)
level8_thread = threading.Thread(target=Level8)
level8_thread.start()
time.sleep(1)
level9_thread = threading.Thread(target=Level9)
level9_thread.start()
time.sleep(1)
level10_thread = threading.Thread(target=Level10)
level10_thread.start()
time.sleep(1)
发布于 2022-08-30 23:00:00
我不熟悉Python,但是我看到了逻辑错误--您在应用程序中使用了"nextValiOrderId“,第一件事就是启动了一堆线程。第二件事情发生了--每个线程都会发送一个请求app.reqIds(1)
现在您需要了解reqIds()函数逻辑是什么(来自这一讨论):
nextValidId方法是一个包装器方法。从客户端,您需要调用reqIds来获得一个订单ID。ib_api.reqIds(-1) reqIds的参数并不重要。而且,它没有返回值。相反,reqIds向IB发送一条消息,当收到响应时,将调用包装器的nextValidId方法。
因此,您多次(几乎同时)调用reqIds(1),最终响应将以nextValidId()回调f-n的形式出现,它将app.nextValidOrderId设置为不断增长的数字,但同时从所有线程读取该数字,这是完全混乱的。
相反,您可以通过以下方式重新组织代码逻辑:--只要求reqIds(1)一次:
但即使这种方法也不理想。如果您需要启动超过50个请求/秒速率( IB的许多其他速率限制之一)的线程,那么在启动新线程之间可能会增加30毫秒的睡眠时间(在创建线程的循环中)。但是现在,如果您再考虑一下应用程序的设计,您就会发现您根本不需要很多线程。
ps:我强烈建议任何Pythonista仔细查看the ib_insync项目,这个项目是由Ewald创建的,它背后有越来越多的社区,每个人都很高兴of ib_insync (用python编写)。这是他们的讨论论坛。
这是github上的insync啦啦队,德米特里
https://stackoverflow.com/questions/73548567
复制相似问题