Moteur de protocole FIX · v1.8 · mai 2026

NexusFIX.
Un moteur qui n'alloue jamais.

Un moteur de protocole FIX en C++23 conçu pour les places qui ne pardonnent pas un heartbeat manqué. Zéro allocation sur le chemin chaud, parsing sub-microseconde, état de session déterministe.
Prévisible. Jusqu'au moindre détail.

nexusfix / session / XCME.PROD.42
C++23 · 0 ALLOC · 247K msg/s

Flux de messages · XCME.PROD.42 · NewOrderSingle ⇄ ExecutionReport

tail -f · live stream
12:04:18.11435=D|49=NEXFIX|56=XCME|34=184221|11=ord-9f2e|55=ESM6|54=1|38=2|40=2|44=5418.25parsed 318 ns
12:04:18.11435=8|49=XCME|56=NEXFIX|34=184222|11=ord-9f2e|17=exec-1|150=0|39=0|55=ESM6|54=1acked 1.2 µs
12:04:18.47135=8|49=XCME|56=NEXFIX|34=184223|11=ord-9f2e|17=exec-2|150=F|39=2|32=2|31=5418.25parsed 296 ns
12:04:19.00035=0 heartbeat|34=184224|49=NEXFIX|56=XCME · 30s intervalsent 84 ns
12:04:19.21435=D|49=NEXFIX|56=XCME|34=184225|11=ord-9f2f|55=NQM6|54=2|38=1|40=2|44=19842.75parsed 304 ns
12:04:19.21535=8|49=XCME|56=NEXFIX|34=184226|11=ord-9f2f|17=exec-3|150=0|39=0acked 1.1 µs
12:04:19.60135=8|49=XCME|56=NEXFIX|34=184227|11=ord-9f2f|17=exec-4|150=F|39=2|32=1|31=19842.50parsed 311 ns
12:04:19.88035=F CancelRequest|34=184228|41=ord-9f2e|11=cxl-7a01|55=ESM6parsed 292 ns
12:04:19.88135=8|49=XCME|56=NEXFIX|34=184229|11=cxl-7a01|17=exec-5|150=4|39=4 · cancelledacked 1.0 µs
247K/s
débit de messages
0
allocations heap sur chemin chaud
412ns
latence parsing p99
3.4×
vs baseline QuickFIX

Le budget de performance.

Chaque chiffre que vous chercheriez dans un runbook de production. Mesuré sous charge, sur du matériel courant, sur un replay déterministe.

Latence de parsing
<500ns
p99, NewOrderSingle. Buffers fixes, itération de champs zero-copy.
Débit
240K+ /s
Par session, mono-cœur. Scaling linéaire sur plusieurs sessions.
Allocations chemin chaud
0
Arenas statiques, ring buffers pré-dimensionnés, décodage in-place.
vs QuickFIX
3×
Plus rapide de bout en bout sur la même workload. Suite de benchmarks reproductible.

Pourquoi les opérateurs
choisissent NexusFIX.

Trois choix d'architecture qui se cumulent. Chacun rend le suivant possible.

1 Couche 1 · Déterminisme

Tail serrée. Pas de surprise à p99.

Files SPSC lock-free, décodeurs de tags sans branchement, inlining du chemin chaud. Le message le plus lent ressemble au plus rapide. C'est sur cela que les places vous évaluent vraiment.

120nsp50 · 240nsp90 · 360nsp99 · 412nsp99.9 · 580ns
2 Couche 2 · Mémoire

Zéro allocation sur le chemin chaud.

Arenas statiques, freelists intrusives, slots de messages à taille fixe. L'allocateur ne tourne jamais pendant que les ordres circulent. Donc le noyau ne vous préempte jamais pour récupérer une page.

QuickFIX /order-flow
allocations heap / msg~14
NexusFIX /order-flow
allocations heap / msg0 · réutilisation d'arena
3 Couche 3 · Protocole

FIX 4.2 / 4.4 / 5.0 / FIXT. Un seul moteur.

Dictionnaires générés par version, sélectionnables à l'exécution par session. Overlays de dialectes personnalisés pour les champs spécifiques aux places. Le format wire qu'utilise la place est celui que vous envoyez.

FIX 4.2complet
FIX 4.4complet
FIX 5.0 SP2complet
FIXT 1.1complet
Customoverlay
Éprouvé sur le wire

Configuré pour les places où vous tradez vraiment.

Profils de session pré-construits pour les principales places actions, futures, FX et crypto. Heartbeats, sémantique de reset de séquence et particularités de resend-request capturées depuis des traces de production réelles.

CMEICENYSENasdaqLSEEurexHKEXSGXEBSRefinitivCoinbase PrimeBinance Inst.

Le hot path,
de deux façons.

Un NewOrderSingle décodé et routé, côte à côte. Même message, même machine, coût très différent.

QuickFIX (C++) application.cpp
void Application::onMessage(const FIX44::NewOrderSingle& msg, const SessionID& sid)
{
  FIX::ClOrdID    clOrdId;   msg.get(clOrdId);       // allocates
  FIX::Symbol     symbol;    msg.get(symbol);        // allocates
  FIX::Side       side;      msg.get(side);
  FIX::OrderQty   qty;       msg.get(qty);           // allocates Decimal
  FIX::Price      price;     msg.get(price);         // allocates Decimal

  std::string key = symbol.getString();          // allocates std::string
  router_->route(key, clOrdId.getString(), qty, price);
}                                                // ~14 heap allocs / msg
p99 parse + route1.42 µs · 14 allocs
NexusFIX (C++23) order_handler.cpp
void OrderHandler::on_message(MessageView m, SessionRef sid) noexcept
{
  auto [cl_ord_id, symbol, side, qty, price] =
      m.decode<D::ClOrdID, D::Symbol, D::Side,
                D::OrderQty, D::Price>();     // in-place, span<const char>

  // fixed-arena order slot, no heap, no copies
  auto& slot = arena_.acquire(cl_ord_id);
  slot.init(symbol, side, qty, price, sid);

  router_.route(slot);                              // 0 heap allocs / msg
}
p99 parse + route412 ns · 0 allocs

Pourquoi les équipes remplacent QuickFIX.

QuickFIX a porté le gros du travail de l'industrie pendant deux décennies. NexusFIX est ce vers quoi on se tourne quand ces choix sont devenus le goulot d'étranglement.

QuickFIXNexusFIX
Allocations sur le hot path~14 allocs heap par message (std::string, Decimal)0 · arènes statiques, decode in-place
Latence p99 de parsing1,2–1,8 µs selon le dialecte< 500 ns · decode de tags sans branchement
Débit / cœur60–90K msg/s soutenu240K+ msg/s soutenu
Comportement de la queue sous chargeSans GC, mais le churn de l'allocateur = pics imprévisiblesAucun allocateur sur le hot path. queue plate
Versions de protocole4.2 / 4.4 / 5.0. Dictionnaire de données XML par build4.2 / 4.4 / 5.0 / FIXT + overlay de dialecte au runtime
LangageIdiomes C++03 / C++11, dispatch virtuelC++23, concepts + ranges, pas de virtual sur le hot path
QuickFIX a été construit quand 5 000 msg/sec représentait une session chargée. NexusFIX est conçu pour les venues où c'est une minute calme. et la queue doit rester plate de toute façon.

Le hot path,
de bout en bout.

Octets sur le câble en entrée. Ordre routé en sortie. Trois étages, tous dans le même thread, tous sans allocation.

1 Étape 1 · Décodage

Octets en entrée, champs en sortie. sans copie.

Le flux séparé par SOH est itéré sur place. Chaque tag se résout en une vue typée sur le buffer original ; les champs numériques sont parsés sans branchement, l'overlay de dialecte est appliqué au moment du bind de session.

span<const char>sans branchementchecksum SIMD
2 Étape 2 · Validation

État de session, de façon déterministe.

Numéros de séquence, fenêtres heartbeat, sémantique gap-fill, particularités resend-request. Géré par une machine à états générée par profil de venue. Chaque transition est journalisée dans un journal memory-mapped.

seq-numheartbeatresendmmap journal
3 Étape 3 · Routage

Dans votre handler, zéro allocation.

Un slot d'ordre dans une arène fixe est acquis, peuplé par référence, et remis à votre application via une queue SPSC sans verrou. Le slot vit jusqu'à l'état terminal de l'ordre, puis retourne à l'arène.

queue SPSCslot d'arènepas de virtual

Allez plus loin.

Deux fils à tirer ensuite. La présentation d'architecture, ou l'explicateur conversationnel en direct.

Branchez-le en un après-midi.

NexusFIX se distribue sous forme d'une bibliothèque statique unique et d'un simulateur de session CLI. Apportez une config de venue et un handler, et vous avez une session FIX déterministe qui tourne en local. Rejouable depuis un journal, traçable à l'octet près.

Explorez d'autres projets.

NexusFIX est l'un des trois moteurs que nous construisons. Même philosophie : open-source quand c'est possible, performance d'abord, pas de lock-in.