Search code examples
javainteractive-brokers

Interactive Broker Java API


Everytime before I place a new order to IB, I need to make a request to IB for next valid orderId and do Thread.Sleep(500) to sleep for 0.5 seconds and wait for IB API's callback function nextValidId to return the latest orderID. If I want to place multiple orders out, then I have to naively do thread.sleep multiple times, This is not a very good way to handle this, as the orderID could have been updated earlier and hence the new order could have been placed earlier. And what if the orderID takes longer time to update than thread sleep time, this would result in error.

Is there a more efficient and elegant way to do this ?

Ideally, I want the program to prevent running placeNewOrder until the latest available orderID is updated and notify the program to run placeNewOrder.

I do not know much about Java data synchronization but I reckon there might be a better solution using synchronized or wait-notify or locking or blocking.

my code:

// place first order
ib_client.reqIds(-1);
Thread.sleep(500);
int currentOrderId = ib_wrapper.getCurrentOrderId();
placeNewOrder(currentOrderId, orderDetails); // my order placement method 
// place 2nd order
ib_client.reqIds(-1);
Thread.sleep(500);
int currentOrderId = ib_wrapper.getCurrentOrderId();
placeNewOrder(currentOrderId, orderDetails); // my order placement method 

IB EWrapper:

public class EWrapperImpl implements EWrapper {
    ...
    protected int currentOrderId = -1;
    ...
    public int getCurrentOrderId() {
        return currentOrderId;
    }

    public void nextValidId(int orderId) {
        System.out.println("Next Valid Id: ["+orderId+"]");
        currentOrderId = orderId;
    }
    ...
}

Solution

  • You never need to ask for id's. Just increment by one for every order.

    When you first connect, nextValidId is the first or second message to be received, just keep track of the id and keep incrementing.

    The only rules for orderId is to use an integer and always increment by some amount. This is per clientId so if you connect with a new clientId then the last orderId is something else.

    I always use max(1000, nextValidId) to make sure my id's start at 1000 or more since I use <1000 for data requests. It just helps with errors that have ids.

    You can also reset the sequence somehow.

    https://interactivebrokers.github.io/tws-api/order_submission.html

    This means that if there is a single client application submitting orders to an account, it does not have to obtain a new valid identifier every time it needs to submit a new order. It is enough to increase the last value received from the nextValidId method by one.