Rejection of FIX order modification: what happens to the original order? - fix-protocol

Could anyone point me to the relevant section of the FIX spec pertaining to rejected order modification?
Please consider the following scenario:
A limit order (NewOrderSingle: ClOrdID='blah.0') is placed and
confirmed as submitted by the broker
Modification request of the order (OrderCancelReplaceRequest:
ClOrdID='blah.1'; OrigClOrdID='blah.0') gets rejected due to, say,
limit violation
What happens to the original order (ClOrdID='blah.0')? Is it still considered valid and can be filled? Does the FIX specification define the expected behavior for such scenarios and the expected state of the original order?

TL;DR
You should consult your counterparty's FIX specification document(s) for the exact behavior to expect from that specific counterparty when an attempt to replace a working order is rejected.
Long answer
Assuming nothing has happened to the original order 11=blah.0 between the time it was placed and the OrderCancelReplaceRequest with 11=blah.1|41=blah.0 was sent and rejected (e.g., fill, partial fill(s), external cancel), the original order 11=blah.0 should still be working, and can be filled.
There is nothing in the FIX specification that states the exact expected outcome when an attempt to replace a working order is rejected. Since most exchanges/brokers use some flavor of FIX 4.2, I'll point to the documentation for that version:
Order Cancel Reject - The order cancel reject message is issued by the
broker upon receipt of a cancel request or cancel/replace request
message which cannot be honored. Requests to change price or decrease
quantity are executed only when an outstanding quantity exists. Filled
orders cannot be changed (i.e quantity reduced or price change.
However, the broker/sellside may support increasing the order quantity
on a currently filled order).
In the message specification it has:
Tag | Field Name | Req'd | Comments
39 | OrdStatus | Y | OrdStatus value after this cancel reject is applied.
Whatever the counterparty provides for OrdStatus in the OrderCancelReject message is the state of the original order. I have never run into any counterparty that cancels the original order when a replace request is rejected, but I suppose it's possible. If a counterparty does handle the situation this way, any documentation provided by the counterparty should clearly state so.

Related

Validating QuickFix/N Repeating Group Where First Two Fields Swap Order

I am implementing a client to connect to a server which as far as I can tell uses a hybrid of FIX4.2 and FIX4.4.
The server sends group 453 (NoPartyIDs) with fields in a non-standard order when some events occur.
According to the specification document, the first field should be PartyID (448). With certain messages, the first field in the group is PartyIDSource (447) and the message is rejected. PartyIDSource is the second field in the group as per the specification.
I get the following error:
<event> Message 140 Rejected: Group 453's first entry does not start with delimiter 448 (Field=453)
From the documentation and trial and error, I cannot find a way through this issue. Amongst a few guesses, I have tried adding field 447 as the first (non-required) field in the group definition in the data-dictionary. I have also set ValidateFieldsOutOfOrder to N in the config.
Is there something I can do to not reject and process the message?
Relevant documentation:
Groups are a little more nuanced than other parts of the Data Dictionary.
A group is defined within a message, with the group tag. The first child element of the group tag is the group-counter tag, followed by the other fields in the group in the order in which they should appear in the message.
ValidateFieldsOutOfOrder is not relevant here, so you can take that out.
If I understand you correctly, you're saying that
sometimes 447 comes before 448
but at other times 448 comes before 447
If this is true, then unfortunately your counterparty is being really stupid. Per the FIX spec, the order of fields in repeating groups is supposed to be in a consistent order. (And also, the first field of the each group-sequence is always required to be present.) If they're flip-flopping fields, they're violating FIX.
If the order was consistent, you would just edit your DD to change the order, and it sounds like you tried that. But if your counterparty is flip-flopping, then your DD will always be wrong part of the time.
I don't have a good answer for you. QF/n is not designed to handle all the ways that counterparties do FIX wrong (nor should it be).
Your counterparty's implementation is sloppy. Try contacting their support and seeing if they'll fix it?

FIX Reject message [duplicate]

I am trying to handle a FIX Reject (MsgType 35=3), but I am unclear on how to retrieve the message that is referred to by the FIX Reject message.
The FIX Reject refers to the rejected message by MsgSeqNum, in the RefSeqNum field (tag 45). However I don't know how to get the rejected message by its sequence number. I think it should be possible because the FIX engine can resend messages in a sequence number range (in response to a resend request), so if the engine can do it so should I.
The question: how do I get the message that is referenced by the reject message in the RefSeqNum field?
Do you want to programmatically handle this failure? Generally the lower level rejects should never happen in the production environment. I have always dealt with them while testing and manual inspection of messages to identify the actual message and the tag having the problem.
In any case you can programmatically get the message by:
First looking up the session using Session Session.lookupSession(SessionID sessionId)
Get the MessageStore associated with the Session using MessageStore Session.getStore()
Obtain the actual message using MemoryStore.get(int startSequence, int endSequence, Collection<String> messsages)
You can find API documentation for QuickFIX/J here, or visit the documentation folder.
Note that in step 3 you will have to pass the same sequence number as the start and the end sequence number.

How FIX Protocol handles chain of request

I have a question regarding FIX Protocol and I'm quite new to it.
A client sent an order and it got accepted by the broker. After that, the client sent a request (request #1) to modify the quantity to x. However, before request #1 is accepted, the client sent another modification request (request #2) to modify the quantity to y.
I search the documentation of FIX Protocol and find these.
The order sender should chain client order ids on an ‘optimistic' basis, i.e. set the OrigClOrdID <41> to the last non rejected ClOrdID <11> sent
The order receiver should chain client order ids on a ‘pessimistic' basis, i.e. set the OrigClOrdID <41> on execution reports that convey the receipt or succesful application of a cancel/replace and Order Cancel Reject <9> messages to be the last ‘accepted' ClOrdID <11> (See "Order State Change Matrices" for examples of this)
However, I still don't understand how FIX Protocol handles request. Will the quantity be modified to y? Or does it depend on which request is being accepted last?
You need to understand that the FIX Protocol is a set of guidelines on how someone who implements the protocol should handle certain scenarios. In practice there are differences in how counterparties handle this.
In your example the quantity should be modified to y in the end. But the quantity will be modified to x first since that message was received at first.
Here are some chaining examples taken from the spec:
https://www.onixs.biz/fix-dictionary/4.4/app_d.html (search for sequencing or chaining)
Here are examples specific to your question where two consecutive replace requests are handled:
https://www.onixs.biz/fix-dictionary/4.4/app_dD.2.a.html
https://www.onixs.biz/fix-dictionary/4.4/app_dD.2.b.html

How can I implement pending orders in FIX protocol?

I have a FIX server which supports open/close positions. Now, I want to add support for pending orders.
In the NewOrderSingle message, there is a field OrdType which defines the type of order, Market,Limit,Stop, etc. I used these ones for position orders. Now I need a parameter for pendings..
I considered adding another parameter to the NewOrderSingle message but wonder if there's a better way..?
I think you are looking at the wrong message type. ExecutionReport has an OrdStatus field that you can set to "pending new".
NewOrderSingle is for a trader to submit an order, and that's all. A trader wouldn't mark his own order as "pending" when he submits it! The server responds to the trader with an ExecutionReport that has the appropriate OrdStatus.
Apologies if I'm telling you things you already know. There's not a lot of context in your question.

What is the relationship between the FIX Protocol's OrdID, ClOrdID, OrigClOrdID?

I'm pretty new to the FIX protocol and was hoping someone could help clarify some terms.
In particular could someone explain (perhaps with an example) the flow of NewOrderSingle, ExecutionReport, CancelReplaceRequest and how the fields ClOrdID, OrdID, OrigClOrdID are used within those messages?
A quick note about usages of fields. My experience is that many who implement FIX do it slightly differently. So be aware that though I am trying to explain correct usage you may find that there are differences between implementations. When I connect to a new broker I get a FIX specification which details exactly how they use the protocol. I have to be very careful to make sure where they have deviated from other implementations.
That said I will give you a rundown of what you have asked for.
There are more complicated orders but NewOrderSingle is the one most used. It allows you to create a trade for any asset. You will need to create a new order using this object / msg type. Then you will send it through your session using the method sendToTarget(). You can modify the message after this point through the toApp() method, assuming your application implements the quickfix.Application interface.
The broker (or whoever you are connected to) will send you a reply in the form of and Execution report. Using quickfix that reply will enter your application through the fromApp() callback. From there the best thing to do is to implement your app inheriting from the MessageCracker class (or implement it elsewhere) using the crack method from MessageCracker it will then call back a relevant onMessage() method call. You will need to implement a number of these onMessage() methods (it depends on specifically what you are doing as to which methods you will need), the main one being onMessage(ExecutionReport msg, SessionID session). This method will be called by message cracker when you receive and Execution report from the broker. This is the standard reply to a new order.
From there you handle the reply as required.
Some orders do not get filled immediately like Limit orders. They can be changed. For that you will need the CancelReplaceRequest. Your broker will give you details of how to do this specifically for them (again there are differences and not everyone does it the same). You will have to have done a NewOrderSingle first and then you will use this MsgType to update it.
ClOrdID is an ID that the client uses to identify the order. It is sent with the NewOrderSingle and returned in the ExecutionReport. The OrdID tag is in the ExecutionReport message, it is the ID that the broker will use to identify the order. OrgClOrdID is usually used to identify the original order in when you do and update (using CancelReplaceRequest), it is supposed to contain the ClOrdID of the original order. Some brokers want the original order only, others want the ClOrdID of the last update, so the first OrigClOrdID or will be the ClOrdID of the NewOrderSingle, then if there are subsequent updates to the same order then they will be the ClOrderID from the last CancelReplaceRequest. Some brokers want the last OrderID and not ClOrderID. Note that the CancelReplaceRequest will require a ClOrdID as well.