IB_Insync - only one order gets auto submitted to TWS; subsequent orders dont go through

31 Views Asked by At

I have been working on this IB_Insync, Asyncio, bot interface into TWS using NGROK, Flask and Redis.

The first webhook payload gets transmitted through to TWS perfectly and the order is placed, but all subsequent orders transmitted through this IB_Insync bot do not go through. No errors are displayed, and the webhook payload is successfully transmitted through NGROK and displayed in the Asyncio message display - so i know the data alert is received. When i stop the script and restart - the first order transmitted is accepted by TWS, but again not the following orders.

I originally thought this may be due to TWS needing unique orderId's, and hence tried numerous ways to do this using either IB_insync reqID methods; including ib.client.getReqId(), and i even tried importing IB_API and using EWrpper nextValidID etc but couldnt get this to work inside the async function.

Nevertheless....throughout the extensive research on StackOverFlow, IB_Insync documentation and insync@groups forum where similar problems are discussed; i stumbled across posts where Erwald deWit (the creator of IB_Insync) has made clear that IB_Insync issues orderID's automatically when the order is placed. Further research has identified unique orderID's assigned with each IB_Insync order. Which explains why there is nothing (that i could find) in the in-sync documentation on how to call/create unique orderId's on each new order and hence why the script not creating unique order numbers may not be the problem.

Could it have something to do with the orders being placed within async function? (i have tried removing but my fresh (albeit rapidly developing) coding knowledge couldnt get it to work) If this is a possible solution can somebody help guide me how contract and order syntax be placed outside of a async function and still receive the message input data?

I was hoping somebody could see where in the code could be preventing TWS from recognizing/accepting orders after the first being placed.

Has anybody experienced similar challenges and found a way to overcome this issue?

Thankyou - i really appreciate your attention and help on this

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
from ibapi.order import Order
import redis, json
from ib_insync import *
import asyncio, time, random

class TradingApp(EWrapper, EClient):
    def __init__(self):
        EClient.__init__(self, self)

    def nextValidId(self, orderId):
        super().nextValidId(orderId)
        self.nextValidId = orderId
        print("NextValidId:", orderId)


# connect to Interactive Brokers 
ib = IB()
ib.connectAsync('127.0.0.1', 7497, clientId=1)

# connect to Redis and subscribe to tradingview messages
r = redis.Redis(host='localhost', port=6379, db=0)
p = r.pubsub()
p.subscribe('tradingview')

async def check_messages():
   print(f"{time.time()} - checking for tradingview webhook messages")
    message = p.get_message()
    if message is not None and message['type'] == 'message':
        print(message)

        message_data = json.loads(message['data'])

        future = Future(message_data ['ticker'], message_data['contractExpDate'], 'CME') # Future(message_data['ticker'], message_data['secId'], message_data['exchange']) 
        order = LimitOrder(message_data['strategy']['order_action'], message_data['strategy']['order_contracts'], message_data['strategy']['limit_price'])
        #order.orderId = ib.client.getReqId() # get new orderID
        #order = MarketOrder(message_data['strategy']['order_action'], message_data['strategy']['order_contracts'])
        trade = ib.placeOrder(future, order)

async def run_periodically(interval, periodic_function):
    while True:
        await asyncio.gather(asyncio.sleep(interval), periodic_function())

asyncio.run(run_periodically(1, check_messages))

ib.run()
0

There are 0 best solutions below