首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何避免多线程应用程序中重复的订单IB和损坏的打印,这要感谢使用IB TWS Python API的队列。

如何避免多线程应用程序中重复的订单IB和损坏的打印,这要感谢使用IB TWS Python API的队列。
EN

Stack Overflow用户
提问于 2022-08-30 21:20:38
回答 1查看 79关注 0票数 2

我用Python编写并使用IB TWS API编写的交易应用程序是多线程的,我希望一劳永逸地解决所有损坏的打印和重复订单IB问题,这两个问题都可以在多个线程同时运行时发生。

为了解决这个问题,我编写了一个简单的脚本,除了为解决这个问题提供支持之外,没有其他任何东西可以达到目标。我希望看到更有经验的人如何实现队列,从而使脚本完成两件事:

  1. 以非腐败的方式打印“安全”
  2. 每个订单都应该在没有出现“重复订单id”错误代码的情况下执行。

我知道我需要使用队列,但我刚刚开始阅读这个主题,而且由于IB TWS API相当具体,我不知道如何实现。谢谢。

代码语言:javascript
运行
复制
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)
EN

回答 1

Stack Overflow用户

发布于 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)一次:

  • 然后什么也不做(发送请求后不执行代码)
  • 延续逻辑将驻留在nextValidId()回调f-n的主体中:从IB获得有效整数后,您将将其设置为应用程序变量,不再调用reqIds(1)。
  • 调用您的"main_continuation()“函数将使用该数字作为参数传递给第一个线程,然后在一个循环中增加这个数字并将其传递给下一个线程,因此在这个情况下,没有一个线程会尝试使用相同的order。

但即使这种方法也不理想。如果您需要启动超过50个请求/秒速率( IB的许多其他速率限制之一)的线程,那么在启动新线程之间可能会增加30毫秒的睡眠时间(在创建线程的循环中)。但是现在,如果您再考虑一下应用程序的设计,您就会发现您根本不需要很多线程。

ps:我强烈建议任何Pythonista仔细查看the ib_insync项目,这个项目是由Ewald创建的,它背后有越来越多的社区,每个人都很高兴of ib_insync (用python编写)。这是他们的讨论论坛

这是github上的insync啦啦队,德米特里

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73548567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档