Handling OrderCancelRequest before receiving NewOrderSingle

Hi everyone,

I would like to understand what is the widely adopted approach to handle the following scenario with FIX 4.4

Let’s say a client has their FIX layer separated from their main systems handing outgoing NewOrderSingle and OrderCancelRequest requests. And the following situation happens:

  1. Client prepares NewOrderSingle with ClOrdID=A (not sent yet).
  2. Client prepares OrderCancelRequest with ClOrdID=B, OrigClOrdID=A (not sent yet)
  3. Client sends OrderCancelRequest with ClOrdID=B, OrigClOrdID=A.
  4. Client sends NewOrderSingle with ClOrdID=A.

As the result, you receive OrderCancelRequest before NewOrderSingle, and all MsgSeqNum are sequential, without gaps and according to FIX protocol.

So, you have to process OrderCancelRequest before NewOrderSingle.

We can imagine several possible ways to process it:

  1. We reject OrderCancelRequest and we accept NewOrderSingle. We have a valid order which is going to be executed. Client receives executions which they may not wanted to get.
  2. We accept OrderCancelRequest and we reject NewOrderSingle. We have an order in Rejected state. Client does not receive executions they don’t want. Order is rejected while client would expect that the order is canceled.
  3. We accept OrderCancelRequest and we accept NewOrderSingle. Order becomes Canceled immediately. Client does not receive execution they don’t want. Order is canceled as the client expect.

In processing approaches 2 and 3 we have to process OrderCancelRequest and store it even though it may not contain all the fields from NewOrderSingle.

Question to the community: What approach are you using in your implementations of FIX protocol? What approach do you think is the best? Would you propose another approach to handle this scenario?

Welcome to the FIX TC :slight_smile:

Option 1.

Failure to maintain proper ordering within an order-chain would be a serious error in a client’s system. They’d be expected to fix this. I can’t imagine a single market participant that would try to do 2 or 3.

At the end of the day as a counter-party you’d be doing the same work that the client could do themselves (buffering and re-ordering FIX) without any knowledge of how long to keep the cancel in context in-case an order arrives.

There is actually an option 4, which is that some market participants might be more strict still and send rejects for both messages on the grounds that the orderIDs were mis-used, but I wouldn’t rely on this behavior.

Mixing verbal (telephone) order requests/execution reports with FIX based flow may thappen in what you described. Catching up referencing and sequencing when different communication lines (when the main line is broken for instance) are involved or switched on/off may be possible but some manual intervention is necessary.

You as a recipient must be agnostic to the system architecture of your clients. When you receive a message, you have to process it in a stateless manner, meaning that you do not try to detect whether the order cancellation was for
a) an order that is about to be submitted with the next incoming message or
b) an order that does not exist

You have to assume the latter and reject the order cancellation with CxlRejReason(102)=1 (Unknown order).

Now comes the new order and, again, you must be agnostic and not try to recognise that the previous message you received had an OrigClOrdID(11) value identical to the ClOrdID(11) value of the current message. You may only check for a duplicate ClOrdID(11) value amongst your existing (and active) orders to possibly reject with OrdRejReason(103)=6 (Duplicate order).

In summary, your FIX engine does not have to recognise the kind of errors made by your clients. They must guarantee that a new order message is sent prior to its cancellation and cannot expect you to do some kind of business level re-ordering of messages.

Agree with @gtcpm and @philipwhiuk - you should not be the one trying to “guess” what is the client’s intentions.

Thank you for the responses! It is super helpful!

I agree with philipwhiuk as well. It is vital to maintain the life cycle of an order properly in the system.

The proper way would be to reject the front running order cancel request with a Order Cancel Reject <9> message with an appropriate text (something like “Order not found”) and process the NOS that is receives afterwards

It is up to the client to handle the reject message and maintain the ordering in the first place in the scenario in my opinion