FIX Execution Report (35=8)
The Execution Report is the broker's response to everything. Send a New Order Single and you get one back. Cancel an order and you get one back. Partial fill, full fill, reject -- all Execution Reports. It's the most important message type in FIX and also the one with the most implementation traps.
ExecType vs OrdStatus
This is where most implementations go wrong. The two fields are related but different:
- ExecType (tag 150) -- what just happened in this report
- OrdStatus (tag 39) -- the current state of the order
On an order acknowledgement, ExecType=0 (New) and OrdStatus=0 (New). Both say the same thing. On a partial fill, ExecType=F (Trade) and OrdStatus=1 (PartiallyFilled). Now they diverge. ExecType tells you a trade happened. OrdStatus tells you the order still has quantity open.
A common mistake is treating them as the same field or only checking one of them. Brokers can and do send combinations that seem redundant until an edge case hits.
| Scenario | ExecType (150) | OrdStatus (39) |
|---|---|---|
| Order acknowledged | 0 = New | 0 = New |
| Partial fill | F = Trade | 1 = PartiallyFilled |
| Full fill | F = Trade | 2 = Filled |
| Cancel confirmed | 4 = Canceled | 4 = Canceled |
| Replace confirmed | 5 = Replace | 0 = New (resets) |
| Order rejected | 8 = Rejected | 8 = Rejected |
| Pending cancel | 6 = PendingCancel | 6 = PendingCancel |
Key Fields
| Tag | Field | Notes |
|---|---|---|
| 11 | ClOrdID | Your order identifier. Echoed back in every report for that order. |
| 14 | CumQty | Total quantity filled so far, cumulative across all fills. |
| 17 | ExecID | Unique identifier for this specific report. Increments with every report sent. |
| 31 | LastPx | Price of this fill. Only present on trade reports (ExecType=F). |
| 32 | LastQty | Quantity of this fill. Only present on trade reports. |
| 37 | OrderID | The broker's identifier for the order. Different from your ClOrdID. |
| 38 | OrderQty | Original order quantity as submitted. |
| 39 | OrdStatus | Current state of the order. See ExecType vs OrdStatus above. |
| 58 | Text | Free text reason, usually populated on rejects. |
| 150 | ExecType | What happened in this specific report. |
| 151 | LeavesQty | Quantity still open. Zero when filled or canceled. |
Example Messages
Paste any of these into the FIX parser to see every tag decoded.
Acknowledgement
8=FIX.4.4|9=160|35=8|34=2|49=BROKER|52=20240115-14:30:02.000|56=OMS|11=ORD-001|14=0|17=EXEC-001|20=0|37=BRKR-001|38=500|39=0|40=2|44=150.25|54=1|55=AAPL|150=0|151=500|10=088|
Partial Fill
8=FIX.4.4|9=180|35=8|34=3|49=BROKER|52=20240115-14:30:05.000|56=OMS|6=150.25|11=ORD-001|14=200|17=EXEC-002|20=0|31=150.25|32=200|37=BRKR-001|38=500|39=1|40=2|44=150.25|54=1|55=AAPL|150=F|151=300|10=112|
Full Fill
8=FIX.4.4|9=180|35=8|34=4|49=BROKER|52=20240115-14:30:08.000|56=OMS|6=150.25|11=ORD-001|14=500|17=EXEC-003|20=0|31=150.25|32=300|37=BRKR-001|38=500|39=2|40=2|44=150.25|54=1|55=AAPL|150=F|151=0|10=199|
Cancel Confirmed
8=FIX.4.4|9=165|35=8|34=5|49=BROKER|52=20240115-14:31:01.000|56=OMS|11=ORD-002|14=0|17=EXEC-004|20=0|37=BRKR-001|38=500|39=4|40=2|41=ORD-001|44=150.25|54=1|55=AAPL|150=4|151=0|10=077|
Reject
8=FIX.4.4|9=170|35=8|34=6|49=BROKER|52=20240115-14:30:03.000|56=OMS|11=ORD-001|14=0|17=EXEC-005|20=0|37=NONE|38=500|39=8|40=2|44=150.25|54=1|55=AAPL|58=Unknown symbol|150=8|151=0|10=143|
Common Implementation Mistakes
Only checking OrdStatus
Some implementations ignore ExecType and only look at OrdStatus to determine what happened. This breaks on pending states and on brokers that send intermediary reports before the final state. Always check both.
Not handling Pending states
PendingCancel (39=6) and PendingNew (39=A) are real states that some brokers send. If your system expects a cancel confirmation and gets a PendingCancel first, it needs to wait for the final Canceled report rather than treating the pending as a failure.
CumQty + LeavesQty math
CumQty + LeavesQty should always equal OrderQty. If it doesn't, something is wrong. This is a quick sanity check worth adding to your processing logic.
Assuming ExecID is sequential
ExecID (tag 17) is unique but not guaranteed to be sequential across sessions or reconnects. Don't use it as a counter. Use it as a unique key for deduplication.
Test your Execution Report handling
FIXSIM lets you trigger any ExecType and OrdStatus combination on demand. No credit card required.