FIX Order Lifecycle Explained
An order on a FIX session is a conversation: the client sends requests, the broker or venue answers each change of state with an Execution Report. This guide follows an order through its common paths, with the values of OrdStatus (39) and ExecType (150) at every step, using FIX 4.4.
The messages involved
- The client sends New Order Single (35=D) to place an order, Order Cancel Request (35=F) to cancel it, Order Cancel/Replace Request (35=G) to change price or quantity, and Order Status Request (35=H) to ask for its state.
- The sell side answers every change of state with an Execution Report (35=8): acknowledgement, fill, cancel, replace, reject, expiry.
- When it refuses a cancel or a replace, it answers with an Order Cancel Reject (35=9) instead. The order carries on unchanged.
The Execution Reports are the record of what happened. Positions, fills and order books on the client side should be built from them, not from the requests that were sent.
Order states (OrdStatus, tag 39)
| 39 | State | Meaning | Final? |
|---|---|---|---|
| A | Pending new | Received by the sell side, not yet accepted. Many venues skip this report. | No |
| 0 | New | Accepted and working, nothing filled. | No |
| 1 | Partially filled | Some quantity filled, the rest still working. | No |
| 2 | Filled | The whole quantity is filled. | Yes |
| 6 | Pending cancel | A cancel request is being processed. | No |
| 4 | Canceled | Canceled; any filled quantity stays filled. | Yes |
| E | Pending replace | A cancel/replace request is being processed. | No |
| 8 | Rejected | Refused by the sell side. | Yes |
| C | Expired | Ended by its time in force, for example a Day order at the close. | Yes |
| 3 | Done for day | No more executions today. A multi-day order can resume the next day. | For today |
When two states apply at once, pending states win. An order that is partly filled and has a cancel in progress reports 39=6, not 39=1.
| From (39) | Event | To (39) |
|---|---|---|
| Pending new (A) | Accepted, 150=0 | New (0) |
| Pending new (A) or New (0) | Rejected, 150=8 | Rejected (8) |
| New (0) | Fill, 150=F | Partially filled (1) or Filled (2) |
| Partially filled (1) | Fill, 150=F | Partially filled (1) or Filled (2) |
| New (0) or Partially filled (1) | Cancel request, 150=6 | Pending cancel (6) |
| Pending cancel (6) | Canceled, 150=4 | Canceled (4) |
| New (0) or Partially filled (1) | Replace request, 150=E | Pending replace (E) |
| Pending replace (E) | Replaced, 150=5 | New (0) or Partially filled (1) |
| New (0) or Partially filled (1) | Expired, 150=C | Expired (C) |
Quantities and prices at each step
- OrderQty (38) is the order size. On a working order, OrderQty = CumQty (14) + LeavesQty (151).
- A fill report carries the fill itself in LastQty (32) and LastPx (31), the running total in CumQty and the average price of all fills in AvgPx (6).
- When an order is canceled, expired or rejected, LeavesQty becomes 0 even though CumQty may be below OrderQty.
New, partial fill, fill
A buy order for 1,000 MSFT at 187.50 is acknowledged, fills 400, then fills the remaining 600.
1. Buy side: New Order Single
8=FIX.4.4|9=142|35=D|49=BUYSIDE|56=SELLSIDE|34=10|52=20261020-09:30:00.000|11=ORD-2001|21=1|55=MSFT|54=1|60=20261020-09:30:00.000|38=1000|40=2|44=187.50|59=0|10=074|
2. Sell side: accepted (150=0, 39=0)
8=FIX.4.4|9=188|35=8|49=SELLSIDE|56=BUYSIDE|34=20|52=20261020-09:30:00.002|37=OID-9001|11=ORD-2001|17=EXEC-9001-1|150=0|39=0|55=MSFT|54=1|38=1000|40=2|44=187.50|151=1000|14=0|6=0|60=20261020-09:30:00.002|10=037|
3. Sell side: partial fill of 400 (150=F, 39=1)
8=FIX.4.4|9=211|35=8|49=SELLSIDE|56=BUYSIDE|34=21|52=20261020-09:30:04.118|37=OID-9001|11=ORD-2001|17=EXEC-9001-2|150=F|39=1|55=MSFT|54=1|38=1000|40=2|44=187.50|32=400|31=187.50|151=600|14=400|6=187.50|60=20261020-09:30:04.118|10=145|
4. Sell side: fill of 600, order complete (150=F, 39=2)
8=FIX.4.4|9=211|35=8|49=SELLSIDE|56=BUYSIDE|34=22|52=20261020-09:30:09.540|37=OID-9001|11=ORD-2001|17=EXEC-9001-3|150=F|39=2|55=MSFT|54=1|38=1000|40=2|44=187.50|32=600|31=187.48|151=0|14=1000|6=187.488|60=20261020-09:30:09.540|10=171|
AvgPx 187.488 is (400 x 187.50 + 600 x 187.48) / 1000.
SOH (0x01) is shown as |. BodyLength (9) and CheckSum (10) are calculated as if every | were SOH.
Open this example in the parserNew, cancel
A sell order is accepted, then canceled. The cancel request has its own ClOrdID and points at the order through OrigClOrdID.
1. Buy side: New Order Single
8=FIX.4.4|9=141|35=D|49=BUYSIDE|56=SELLSIDE|34=11|52=20261020-09:35:00.000|11=ORD-2002|21=1|55=MSFT|54=2|60=20261020-09:35:00.000|38=500|40=2|44=188.00|59=0|10=038|
2. Sell side: accepted
8=FIX.4.4|9=186|35=8|49=SELLSIDE|56=BUYSIDE|34=23|52=20261020-09:35:00.002|37=OID-9002|11=ORD-2002|17=EXEC-9002-1|150=0|39=0|55=MSFT|54=2|38=500|40=2|44=188.00|151=500|14=0|6=0|60=20261020-09:35:00.002|10=216|
3. Buy side: Order Cancel Request
8=FIX.4.4|9=143|35=F|49=BUYSIDE|56=SELLSIDE|34=12|52=20261020-09:36:10.000|41=ORD-2002|37=OID-9002|11=ORD-2002-C1|55=MSFT|54=2|38=500|60=20261020-09:36:10.000|10=110|
4. Sell side: pending cancel (150=6, 39=6)
8=FIX.4.4|9=201|35=8|49=SELLSIDE|56=BUYSIDE|34=24|52=20261020-09:36:10.002|37=OID-9002|11=ORD-2002-C1|41=ORD-2002|17=EXEC-9002-2|150=6|39=6|55=MSFT|54=2|38=500|40=2|44=188.00|151=500|14=0|6=0|60=20261020-09:36:10.002|10=248|
5. Sell side: canceled (150=4, 39=4)
8=FIX.4.4|9=199|35=8|49=SELLSIDE|56=BUYSIDE|34=25|52=20261020-09:36:10.004|37=OID-9002|11=ORD-2002-C1|41=ORD-2002|17=EXEC-9002-3|150=4|39=4|55=MSFT|54=2|38=500|40=2|44=188.00|151=0|14=0|6=0|60=20261020-09:36:10.004|10=165|
The pending cancel report is optional; many venues go straight to 150=4. If the order fills before the cancel arrives, the answer is an Order Cancel Reject with 102=0 instead.
SOH (0x01) is shown as |. BodyLength (9) and CheckSum (10) are calculated as if every | were SOH.
Open this example in the parserNew, replace, fill
The client raises the limit price from 187.00 to 187.40. After the replace is confirmed, the order is known by the ClOrdID of the replace.
1. Buy side: New Order Single at 187.00
8=FIX.4.4|9=142|35=D|49=BUYSIDE|56=SELLSIDE|34=13|52=20261020-09:40:00.000|11=ORD-2003|21=1|55=MSFT|54=1|60=20261020-09:40:00.000|38=1000|40=2|44=187.00|59=0|10=076|
2. Sell side: accepted
8=FIX.4.4|9=188|35=8|49=SELLSIDE|56=BUYSIDE|34=26|52=20261020-09:40:00.002|37=OID-9003|11=ORD-2003|17=EXEC-9003-1|150=0|39=0|55=MSFT|54=1|38=1000|40=2|44=187.00|151=1000|14=0|6=0|60=20261020-09:40:00.002|10=046|
3. Buy side: Order Cancel/Replace Request to 187.40
8=FIX.4.4|9=169|35=G|49=BUYSIDE|56=SELLSIDE|34=14|52=20261020-09:41:00.000|41=ORD-2003|37=OID-9003|11=ORD-2003-R1|21=1|55=MSFT|54=1|60=20261020-09:41:00.000|38=1000|40=2|44=187.40|59=0|10=006|
4. Sell side: pending replace (150=E, 39=E)
8=FIX.4.4|9=203|35=8|49=SELLSIDE|56=BUYSIDE|34=27|52=20261020-09:41:00.002|37=OID-9003|11=ORD-2003-R1|41=ORD-2003|17=EXEC-9003-2|150=E|39=E|55=MSFT|54=1|38=1000|40=2|44=187.00|151=1000|14=0|6=0|60=20261020-09:41:00.002|10=122|
5. Sell side: replaced (150=5, 39=0)
8=FIX.4.4|9=203|35=8|49=SELLSIDE|56=BUYSIDE|34=28|52=20261020-09:41:00.004|37=OID-9003|11=ORD-2003-R1|41=ORD-2003|17=EXEC-9003-3|150=5|39=0|55=MSFT|54=1|38=1000|40=2|44=187.40|151=1000|14=0|6=0|60=20261020-09:41:00.004|10=095|
6. Sell side: filled under the new ClOrdID
8=FIX.4.4|9=214|35=8|49=SELLSIDE|56=BUYSIDE|34=29|52=20261020-09:43:12.310|37=OID-9003|11=ORD-2003-R1|17=EXEC-9003-4|150=F|39=2|55=MSFT|54=1|38=1000|40=2|44=187.40|32=1000|31=187.40|151=0|14=1000|6=187.40|60=20261020-09:43:12.310|10=064|
In FIX 4.4 the replace confirmation carries 150=5 and the order's state in OrdStatus (39). FIX 4.2 used 39=5 for the same report.
A further cancel or replace would use ORD-2003-R1 as OrigClOrdID (41).
SOH (0x01) is shown as |. BodyLength (9) and CheckSum (10) are calculated as if every | were SOH.
Open this example in the parserNew, reject
An order for an account the broker does not recognise is rejected. The order never becomes active.
1. Buy side: New Order Single
8=FIX.4.4|9=152|35=D|49=BUYSIDE|56=SELLSIDE|34=15|52=20261020-09:45:00.000|11=ORD-2004|1=ACC-404|21=1|55=MSFT|54=1|60=20261020-09:45:00.000|38=1000|40=2|44=187.50|59=0|10=090|
2. Sell side: rejected (150=8, 39=8, 103=15)
8=FIX.4.4|9=215|35=8|49=SELLSIDE|56=BUYSIDE|34=30|52=20261020-09:45:00.002|37=NONE|11=ORD-2004|17=EXEC-9004-1|150=8|39=8|55=MSFT|54=1|38=1000|40=2|44=187.50|151=0|14=0|6=0|103=15|58=Unknown account ACC-404|60=20261020-09:45:00.002|10=151|
SOH (0x01) is shown as |. BodyLength (9) and CheckSum (10) are calculated as if every | were SOH.
Open this example in the parserA rejected replace or cancel is different: it produces an Order Cancel Reject (35=9) and the order stays as it was. See Order rejected for the reason codes.
What changes in FIX 4.2
- Every Execution Report carries ExecTransType (20): 0 for new events, 1 for a bust, 2 for a correction, 3 for a status report. FIX 4.3 removed it.
- Fills are 150=1 and 150=2 instead of 150=F.
- A replace confirmation carries 39=5.
Questions
- What is the difference between OrdStatus (39) and ExecType (150)?
- ExecType says what event this report describes, such as a fill or a cancel. OrdStatus says the state of the order after that event. A fill that completes the order is 150=F with 39=2.
- Which order states are final?
- Filled (2), Canceled (4), Rejected (8) and Expired (C). Done for day (3) is final for the trading day only.
- Do I need to send a new ClOrdID with a cancel?
- Yes. Every request gets its own ClOrdID, and OrigClOrdID (41) points at the order being canceled or replaced.