2

I am trying to use python to place orders through the TWS API. My problem is getting the next valid order ID.

Here is what I am using:

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.common import TickerId
from ibapi import contract, order, common
from threading import Thread

class ib_class(EWrapper, EClient):

    def __init__(self, addr, port, client_id):
        EClient.__init__(self, self)
        self.connect(addr, port, client_id) # Connect to TWS
        thread = Thread(target=self.run, daemon=True)  # Launch the client thread
        thread.start()

    def error(self, reqId:TickerId, errorCode:int, errorString:str):
        if reqId > -1:
            print("Error. Id: " , reqId, " Code: " , errorCode , " Msg: " , errorString)

    def nextValidId(self, orderId: int):
        self.nextValidId = orderId

ib_api = ib_class("127.0.0.1", 7496, 1)

orderID = ib_api.nextValidId(0)

And this gives me :

TypeError: 'int' object is not callable
helloimgeorgia
  • 311
  • 1
  • 10

2 Answers2

2

The nextValidId method is a wrapper method. From the client, you need to call reqIds to get an Order ID.

ib_api.reqIds(-1)

The parameter of reqIds doesn't matter. Also, it doesn't have a return value. Instead, reqIds sends a message to IB, and when the response is received, the wrapper's nextValidId method will be called.

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
MatthewScarpino
  • 5,672
  • 5
  • 33
  • 47
-1

Add some delay after reqIds

In the wrapper class for receiving updates from ibapi, override nextValidId function as it is used by ib_api.reqIds to respond back.

from ibapi.wrapper import iswrapper

@iswrapper
def nextValidId(self, orderId: int):
    super().nextValidId(orderId)
    print("setting nextValidOrderId: %d" % orderId)
    self.nextValidOrderId = orderId

Then, add some delay after calling reqIds as TWS Api might take some time to respond and access it via ib_api.nextValidOrderId

ib_api.reqIds(ib_api.nextValidOrderId)
time.sleep(3)
print("Next Order ID: ", ib_api.nextValidOrderId)

Note: ib_api holds the object for above wrapper class

Abhishake Gupta
  • 2,939
  • 1
  • 25
  • 34
  • don't add delays after reqIds, if you have to synchronize asynchronous code, use synchronization primitives such as `threading.Event`. Create an event, call reqIds, then call wait(), then in nextValidId, use set() to signal that the next valid id has been received which will release the lock and let wait() end so you can go to next line. Do not call sleep, let the main thread work. This way you won't have to make up numbers and your system will be responsive, it will stop waiting immediately after next valid id is received. Do this for everywhere you call sleep. There is no reason to call it. – nurettin Jun 16 '22 at 08:03
  • Thanks @nurettin I will read about thread event and try this. – Abhishake Gupta Jun 17 '22 at 10:00