FIX for crypto exchanges: how institutions connect over FIX 4.4
Institutions trade over FIX. On a crypto exchange with FIX 4.4 they hold a numbered session over TCP, send each order as a NewOrderSingle and get every fill and cancel back as an ExecutionReport.
FIX, the Financial Information eXchange protocol, is the open message standard that banks, asset managers, brokers and exchanges use to send each other orders and executions. An institution that connects to a crypto exchange over FIX 4.4 holds one long-lived session over TCP, sends each order as a NewOrderSingle message and receives every acknowledgement, fill and cancel as an ExecutionReport. Every message is numbered, so nothing is lost when the line drops, and that guarantee is the main reason institutions ask for FIX.
What FIX is, and who uses it
FIX is maintained by the FIX Trading Community, a non-profit standards body, and has been in use for more than thirty years. Its own description lists digital assets among the asset classes it covers, next to equities, bonds, foreign exchange and derivatives. It is an application-layer protocol: it defines what a message means, not how it travels, although the classic form is plain text over TCP.
In that classic form, each field is a number called a tag, an equals sign and a value, and fields are separated by a single control character. Tag 54 is the side, tag 38 the quantity, tag 44 the price. Because every venue uses the same tags, an institution's order management system can connect to a new exchange without learning a new language.
The community still supports two older versions, 4.2 and 4.4, alongside FIX Latest, which it recommends for new work. The FIX 4.4 specification carries errata from June 2003, and the message and tag numbers in this guide were checked against the community's FIX 4.4 reference.
The firms that connect over FIX are professionals: funds and asset managers sending orders from their own trading systems, brokers routing client orders, and the market makers who keep a book liquid. Retail customers never see it.
The session: one connection, numbered messages
A FIX connection is a session between two named parties. Each side has a CompID, agreed during onboarding: here the client is FUND01 and the exchange is EXCH. The client opens a TCP connection to the exchange's host and port, usually protected with TLS, which the community's FIX over TLS (FIXS) standard treats as a requirement.
Every message starts with the same header and ends with the same trailer:
8BeginString,FIX.4.4, always first;9BodyLength, the number of bytes up to the checksum;35MsgType, the kind of message, always third;49SenderCompID and56TargetCompID, who is talking to whom;34MsgSeqNum, the message's sequence number;52SendingTime, in UTC;10CheckSum, three digits, always last.
The session opens with a Logon, MsgType A. It carries EncryptMethod (98=0, none, since TLS does that job), the heartbeat interval in seconds (108=30) and, where the exchange asks for them, a Username (553) and Password (554). The exchange checks the CompIDs, the credentials and the address the connection comes from, and answers with a Logon of its own. A Logout, MsgType 5, ends the session cleanly.
8=FIX.4.4|9=65|35=A|49=FUND01|56=EXCH|34=1|52=20261026-08:00:00.000|98=0|108=30|10=162|Heartbeats
When a side has sent nothing for the agreed 30 seconds, it sends a Heartbeat, MsgType 0. If nothing at all has arrived from the other side for a little longer than that, it sends a Test Request, MsgType 1, with an identifier in tag 112. The answer must be a Heartbeat carrying the same 112. If none comes, the connection is treated as lost, it is closed, and the client logs on again.
Sequence numbers, resends and gap fills
Each side numbers its own messages 1, 2, 3 in tag 34, and the numbers carry on across reconnections until the scheduled reset. The receiver checks every number. If the exchange expects message 6 from FUND01 and receives 7, it knows one is missing.
The gap. The exchange sends a Resend Request, MsgType
2, with BeginSeqNo7=6and EndSeqNo16=0, where 0 means every message from 6 onwards.The resend. The client sends message 6 again, marked PossDupFlag
43=Y, a possible duplicate, so the exchange can tell it from a new message.The gap fill. For messages not worth sending again, such as heartbeats or an order that has gone stale, the client sends a Sequence Reset, MsgType
4, with GapFillFlag123=Yand NewSeqNo36set to the next number.
A number lower than expected without the duplicate flag is treated as a serious error, and the session is ended. That strictness is the point: after any disconnection, both sides end up with every message, in order, exactly once.

An order, tag by tag
An order is a NewOrderSingle, MsgType D. In the example, with illustrative values, the fund buys 2 bitcoin against euros with a limit order at 60,000 euros, good till cancelled. The | stands for the control character between fields.
8=FIX.4.4|9=131|35=D|49=FUND01|56=EXCH|34=12|52=20261026-09:30:00.000|11=ORD-1001|55=BTC/EUR|54=1|60=20261026-09:30:00.000|38=2|40=2|44=60000|59=1|10=190|Tag | Name | Value | Meaning |
|---|---|---|---|
11 | ClOrdID | ORD-1001 | The client's own order ID, unique for at least the trading day |
55 | Symbol | BTC/EUR | The market, in the exchange's own published symbols |
54 | Side | 1 | Buy (2 is Sell) |
38 | OrderQty | 2 | Two bitcoin |
40 | OrdType | 2 | Limit (1 is Market) |
44 | Price | 60000 | The limit price in euros |
59 | TimeInForce | 1 | Good Till Cancel (3 is Immediate or Cancel, 4 is Fill or Kill) |
60 | TransactTime | 20261026-09:30:00.000 | When the client released the order, in UTC |

ExecutionReport: everything that happens to the order
The exchange answers every change with an ExecutionReport, MsgType 8. Two fields carry the meaning: ExecType (150) says what this report is about, and OrdStatus (39) says where the order stands now. The quantities travel with them: CumQty (14) filled so far, LeavesQty (151) still open, and AvgPx (6) the average price. A fill adds LastQty (32) and LastPx (31). The exchange's own OrderID (37) and a unique ExecID (17) for each report complete it.
Behind these messages, the exchange's matching engine is doing the work described in what happens when you press Buy. Over FIX, the client sees it like this:
Accepted.
150=0New,39=0New. Nothing filled, 2 open.Partly filled. 0.5 bitcoin trades at 59,990.
150=FTrade,39=1Partially filled,32=0.5,31=59990,14=0.5,151=1.5,6=59990.Cancel requested. The fund cancels the rest with an OrderCancelRequest, MsgType
F. It gives the cancel a new ClOrdID (11=ORD-1002) and names the order it is cancelling in OrigClOrdID (41=ORD-1001), with the side, symbol, quantity and time.Cancelled. The exchange may first confirm
150=6Pending Cancel, then sends150=4Canceled,39=4Canceled, with14=0.5and151=0. The 0.5 bitcoin already bought stays bought.
Had the order filled completely, the last report would read 150=F and 39=2 Filled, with nothing left open. Had the cancel arrived too late, the exchange would answer with an Order Cancel Reject, MsgType 9. The rule the specification gives keeps the arithmetic honest: while an order is live, LeavesQty equals OrderQty minus CumQty.

FIX, REST or WebSocket
Most exchanges offer more than one way in, because each suits a different client.
FIX | REST API | WebSocket API | |
|---|---|---|---|
Connection | One long-lived session | A separate request for each call | One long-lived stream |
Ordering and recovery | Numbered, with resend and gap fill | Each call stands alone | Usually no replay: reload a snapshot after a drop |
Message format | One standard, the same at every venue | The exchange's own, usually JSON | The exchange's own, usually JSON |
Typical users | Institutions' trading systems | Apps, bots, back-office jobs | Live prices, order books, account updates |
FIX can carry market data too, with a Market Data Request (V) answered by a full snapshot (W) and incremental updates (X), but many crypto venues stream prices over WebSocket and keep FIX for order entry. Marengo, our exchange, has FIX 4.4.
Certification and connectivity testing
The exchange gives each client a test session with its own CompIDs, and the client runs through a certification script before it gets production access. A typical script covers:
logon and logout, with wrong credentials rejected;
heartbeats, and a Test Request answered in time;
a forced sequence gap, a Resend Request, a resend with PossDupFlag and a gap fill;
a new order, a partial fill, a full fill, a cancel and a cancel reject;
orders that must be rejected: an unknown symbol, a price outside limits, a duplicate ClOrdID;
a disconnection in the middle of trading, then a clean recovery.
Alongside it the exchange publishes its rules of engagement: which tags it requires, its symbols, price and quantity precision, message rate limits and the session schedule. The community's Orchestra standard lets a venue publish those rules in machine-readable form, so a client can load them rather than retype them. Connectivity is set up at the same time: allowed IP addresses, TLS certificates, and separate CompIDs for test and production.
What institutions expect
These are the questions an institution asks before it connects.
Drop copy. A separate, read-only session that receives a copy of every ExecutionReport for the firm's accounts, whichever channel the order came through. Risk and operations teams watch positions there without touching the trading session.
Stable session times. Crypto trades all week, but a FIX session still has a schedule: a published window when sequence numbers reset and maintenance happens, at the same time every week, and announced well in advance if it ever moves.
Cancel on disconnect. An option to cancel a client's resting orders when its session drops, so nothing trades while it cannot see the market.
One version of the truth. The same fill, at the same price and time, on FIX, on the REST API, on the drop copy and on the statement, which comes down to a double-entry ledger and regular reconciliation.
Clear rejects. A reason in the Text field (
58) and in the reject codes, never an order that silently disappears.

Frequently asked questions
Is FIX faster than a REST API? A persistent session saves the cost of setting up a connection for each request, but speed is not the main gain. The gain is that every message arrives in order and anything missed is recovered. For the lowest latency, the community also defines binary encodings of the same messages.
Why FIX 4.4 rather than FIX Latest? FIX 4.4 is one of the two older versions the community still supports, and many existing trading systems already speak it. FIX Latest is recommended for new work, and the community's extension packs are backwards compatible, so they can be used with 4.4 too.
Can an exchange stream prices over FIX? Yes, with the Market Data Request and its snapshot and incremental messages. Many crypto venues stream prices over WebSocket instead and use FIX for orders, drop copy and certification.
See it working
FIX is easiest to judge on a working exchange. Open Marengo at marengo.paynoramic.com to see Lite and Pro, or read how our white-label crypto exchange is built and handed over to the licensed operator who runs it.



