Order and cancel rejects
Order rejected: Execution Report 39=8 with OrdRejReason (103)
The order passed session validation but the broker or venue refused it. You get an Execution Report (35=8) with 150=8 and 39=8, a reason code in OrdRejReason (103) and usually an explanation in Text (58).
What it means
There are three levels of reject in FIX. A session Reject (35=3) means the message was malformed. A Business Message Reject (35=j) means the application could not process it and no more specific reject exists. An Execution Report with 39=8 means the order was understood and refused.
A rejected replace does not produce 39=8. It produces an Order Cancel Reject (35=9), and the original order stays live.
OrdRejReason (103) is often coarse: many venues send 0 or 99 and put the real reason in Text (58). Read both.
Common causes
- Unknown symbol, or the instrument identifier is in a form the venue does not use (SecurityIDSource (22) and SecurityID (48)).
- Market closed or the order arrived outside the session.
- Pre-trade risk: credit, position or order-size limits.
- A duplicate ClOrdID (11) for this trading day.
- An order type or time in force the venue does not support.
- Unknown or unauthorised Account (1).
How to fix it
On the side that sent the order
- Read OrdRejReason (103) and Text (58) together.
- Use a new ClOrdID when you send the corrected order.
- Check limits and account set-up with the broker when the reason is credit or limits.
On the side that rejected it
- Use the most specific OrdRejReason (103) code available and a plain Text (58).
- Echo ClOrdID (11) and the order fields so the client can match the reject without looking up the order.
Common OrdRejReason (103) codes
| Code | What it usually means |
|---|---|
| 0 | Broker or exchange option: a broker or venue rule outside the codes below. Check 58. |
| 1 | Unknown symbol: the instrument is not recognised, or identified in an unexpected way. |
| 2 | Exchange closed: outside trading hours or the market is halted. |
| 3 | Order exceeds limit: a size, value or credit limit was breached. |
| 4 | Too late to enter: the trading phase no longer accepts new orders. |
| 5 | Unknown order: used when a referenced order cannot be found. |
| 6 | Duplicate order: the ClOrdID was already used. |
| 8 | Stale order: the order arrived too long after it was created. |
| 11 | Unsupported order characteristic: order type, time in force or instruction not supported. From FIX 4.3. |
| 13 | Incorrect quantity: below the minimum, not a lot-size multiple, or zero. From FIX 4.4. |
| 15 | Unknown account: the Account (1) is not set up for this session. From FIX 4.4. |
| 99 | Other: see Text (58). From FIX 4.4. |
Example
A New Order Single for a symbol the venue does not list, and the reject.
1. Buy side: New Order Single
8=FIX.4.4|9=144|35=D|49=BUYSIDE|56=SELLSIDE|34=190|52=20261020-11:10:00.000|11=ORD-1030|21=1|55=MSFTX|54=1|60=20261020-11:10:00.000|38=1000|40=2|44=187.50|59=0|10=204|
2. Sell side: Execution Report, rejected with 103=1
8=FIX.4.4|9=172|35=8|49=SELLSIDE|56=BUYSIDE|34=1230|52=20261020-11:10:00.002|37=NONE|11=ORD-1030|17=EXEC-1230|150=8|39=8|103=1|58=Unknown symbol MSFTX|55=MSFTX|54=1|38=1000|151=0|14=0|6=0|10=231|
SOH (0x01) is shown as |. BodyLength (9) and CheckSum (10) are calculated as if every | were SOH.
Open this example in the parserQuestions
- Can I reuse the ClOrdID of a rejected order?
- Avoid it. Many venues keep every ClOrdID received during the day, rejected or not, and will reject the second order as a duplicate.
- Why is LeavesQty 0 on a reject?
- A rejected order is not working, so nothing is left to execute. LeavesQty (151) is 0 and CumQty (14) is 0.