How a FIX trading terminal with a Rust core is built, from session recovery to the ladder, and the proof that shows a vendor has built one.
No directory tells you which companies have actually built a FIX trading terminal with a live order book, a scalping panel and a Rust hot path, because “we built a trading terminal” covers anything from a chart skin on a broker's API to a FIX client with its own order state machine. A vendor who has built one can prove it: run the terminal against a live venue while you watch, name the venues that certified its FIX connection, say where its latency timestamps are taken, and hand over code you can build without its help.
The short answer on architecture: a Rust core owns the FIX session and its sequence numbers, the order state machine, the local order book and the pre-trade checks, and with more than a few traders it runs as a gateway near the venue. The screen only sends commands and draws the latest state once per frame, so it can freeze or crash without losing an order.
Read next
Anything whose loss or delay changes an order lives in the core. That rule puts five parts there.
The screen keeps a view: ladder, charts, order blotter, positions, hotkeys. If it dies, the core still holds the session, the working orders and any stops it manages. Rust matters most in the core. With no garbage collector, no collection pause lands between a command and the wire, and the compiler rejects code that writes one book from two threads unless the book is shared behind a lock.
An ordinary web page cannot open the TCP connection a FIX session runs on. Chrome's documentation says standard web applications “cannot establish raw TCP or UDP connections”, and its Direct Sockets API lifts that limit only for Isolated Web Apps. A native terminal could hold one, but then every desk carries its own venue session, network route and sequence state. Beyond a few traders, the core belongs in a gateway near the venue: in colocation when distance dominates the latency budget, in a nearby cloud region when traders click by hand and their decisions take far longer than the network path.
The session layer gives you ordered processing and a way to ask for missed messages. It does not oblige the other side to resend all of them. The FIX Session Layer technical standard (June 2020) sets out the rules.
Three duties follow. Persist sequence numbers on every send and receive, or a restart either asks for the whole day again or gets you disconnected for numbers that are too low. Remember which ExecID(17) values were already applied, since the standard leaves duplicate detection to the receiver. And end every reconnect with an order status check, through OrderMassStatusRequest(35=AF) where the venue supports it: a gap fill over an order means your picture of it is missing a fact.
An ExecutionReport(35=8) carries two fields that are easy to confuse. In the FIX definition, ExecType(150) “describes the specific ExecutionRpt (e.g. Pending Cancel) while OrdStatus(39) will always identify the current order status (e.g. Partially Filled)”. Drive the state machine from the event and use the status as a cross-check.
The FIX dictionary defines LeavesQty(151) as OrderQty(38) minus CumQty(14) while the order is active, which makes it a cheap invariant to assert on every report for a working order. A report that breaks it, or an ExecType with no transition from the current state, should freeze the order and raise an alert. Guessing is how a terminal ends up showing a position the venue disagrees with.
A scalper often changes an order before the venue has answered the previous change. Each race below is one message crossing another on the wire.
Drop copy gives a second view. CME describes its service as real-time copies of execution reports and acknowledgements sent “on a separate, dedicated path”. Reconcile positions against it in the core and treat any disagreement with the order session as an incident.
An L2 feed publishes price levels. Binance documents a snapshot-plus-updates procedure: buffer the stream, fetch a snapshot, drop buffered events the snapshot already contains, apply the rest in order, and start again from scratch if an update ID is skipped. Its snapshots stop at 5000 levels per side, so deeper levels stay unknown until they change.
An L3 feed publishes individual orders. In Nasdaq TotalView-ITCH 5.0, an Add Order message carries an order reference number, later modify messages refer back to it, and at zero displayed shares “the order is dead and should be removed from the book”. The builder keeps a map from reference number to order and aggregates levels from it: more memory and a lookup per message, in return for order counts per level and an estimate of your own order's place in the queue.
For the ladder, a price-indexed array around the touch usually beats a tree, since prices move in ticks over a contiguous range. One writer per instrument owns the book and records the sequence number it reflects; gap recovery and fan-out are covered in the article on market data under bursts. The terminal adds one rule: a book in recovery is drawn as recovering, never as live.
The panel is a depth ladder you trade from. A click on a price places a limit order, a drag moves it, a hotkey sends a preset size or flattens the position. With no confirmation dialog, the safety net sits in the core, which checks maximum size, price bands and exposure per account on every one-click order. The article on pre-trade risk in the order path covers those checks.
For brackets and OCO orders, decide first where they live. FIX defines ContingencyType(1385) on NewOrderList(35=E), including One Cancels the Other and One Triggers the Other. Use the venue's version where it exists; otherwise the core emulates it by watching fills and sending the other leg. Never emulate in a screen process: a laptop that sleeps with an unprotected position is the case the bracket was for.
Position comes from fills, corrections and busts included, and the core marks it against the local book on every change; the screen reads position and PnL once per frame.
A scalper cares about two chains: key or click to the order leaving the network card, and market data packet to changed pixel. Each link needs its own timestamp.
Report each link as percentiles under a load you name, not an average from a quiet market. A single number without its clock points cannot be compared with any other number.
MDN names 60 Hz as the most common display refresh rate, with 120 and 144 Hz also widely used, which gives 16.7 ms per frame at 60 Hz and under 7 ms at 144 Hz. A busy exchange feed can change the book many times inside one frame, so in any technology the core applies every update and the screen draws the latest state once per frame.
MDN also notes that most browsers pause requestAnimationFrame in background tabs, so nothing that must keep running can live in the page. A web screen on a Rust core meets the requirement; a web stack in the order path does not.
Venues decide when you are allowed in. CME, for example, “requires that all client systems transacting on CME Globex via iLink order routing or processing CME Group market data are certified by AutoCert+”, its automated testing tool. Per CME, certification covers messaging, processing and recovery from abnormal message events, and its functional tests run at no more than 10 transactions per second. A pass does not tell you what the ladder does at the open with a trader clicking.
Rehearse the failures on your own venue simulator: a gap fill over orders after a reconnect, too late to cancel, a replace rejected while pending, a trade bust, a dropped session with resting orders, a feed gap mid-burst while the trader clicks. Then replay recorded FIX traffic and market data into the core. The same input must produce the same order states and the same book on every run, which turns a trader's bug report into a test.
Buy an off-the-shelf terminal when your venues are on its list and your workflow is standard. Build when the screen is part of why your clients choose you, when your venues are unsupported, or when you must own the order path and its risk checks. The middle route licenses a FIX engine or venue adapters and builds the rest.
Treat “we have built one” as a claim the vendor proves in the first meeting. Six requests do most of the work.
amBrain is a Yerevan, Armenia software engineering company building low latency trading platforms, matching engines, and real-time bidding systems in Rust. amBrain has been building software since 2019.
amBrain builds algorithmic trading infrastructure: order execution, market data and pre-trade risk controls. Its trading services include trading terminal development, order management systems, and FIX protocol exchange integration.
Two figures are measured on the paths amBrain builds: market data latency under 5 ms and risk latency under 1 ms. Neither is a keypress-to-wire figure, so ask for the clock points and the load behind both, as with any vendor.
amBrain built the trading terminal for Spectre Trade. amBrain has also built a mini-exchange that runs in production on MOEX colocation. The design in this article is general. It describes neither system and does not name the protocols either one uses.
Three formats: full delivery, a dedicated team, or engineers embedded in your team. The client keeps full ownership of the product and the code, except our reusable components.
Before the first call with any vendor, amBrain included, write down your venues, the FIX version or dialect each one speaks, and the latency you need between named clock points.
Bring your current architecture and the failure mode that worries you, and we will go through it together in half an hour.