A high-performance, zero-dependency Financial Information eXchange (FIX) protocol engine written in modern C++17. Designed for ultra-low latency trading systems, exchanges, and financial market infrastructure.
FIX Engine provides a complete implementation of the FIX protocol (versions 4.2 and 4.4) with a focus on minimal latency and zero-allocation message parsing. The engine includes a full session-layer state machine, TCP transport, message construction, and a counterparty simulator for testing.
- Zero-allocation message parsing — stack-based parser with no heap allocations on the hot path
- Sub-microsecond parse latency — optimized for cache locality and branch prediction
- Complete session state machine — logon/logout handshake, heartbeat management, gap detection and recovery
- Dual-mode TCP transport — operates as both acceptor (server) and initiator (client)
- Sequence number management — message store, resend requests, gap-fill, and sequence reset
- No external dependencies — built entirely on the C++ standard library and POSIX sockets
- Counterparty simulator — mock exchange for end-to-end testing and demonstration
- Comprehensive test and benchmark suites
┌──────────────────────────────────────────────────────────┐
│ Application Layer │
│ (Callbacks: app messages, session events) │
└──────────────────────────┬───────────────────────────────┘
│
┌──────────────────────────▼───────────────────────────────┐
│ FIXSession (State Machine) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Inbound: parse loop → sequence validation → dispatch│ │
│ │ Outbound: build message → store → send callback │ │
│ │ State: DISCONNECTED → LOGON_SENT → ACTIVE │ │
│ │ → LOGOUT_SENT → DISCONNECTED │ │
│ └─────────────────────────────────────────────────────┘ │
└──────────────────────────┬───────────────────────────────┘
│
┌──────────────────────────▼───────────────────────────────┐
│ FIXEngine (TCP Transport) │
│ ┌────────────────────┐ ┌─────────────────────────────┐ │
│ │ I/O Thread │ │ Timer Thread │ │
│ │ poll() → read(8KB) │ │ sleep(1s) → on_timer_tick() │ │
│ │ → session dispatch │ │ → heartbeat / test request │ │
│ └────────────────────┘ └─────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
| Component | Header | Description |
|---|---|---|
| FIXParser | include/fix/fix_parser.h |
Zero-copy message parser with checksum validation, fast integer/float conversion |
| FIXMessageBuilder | include/fix/fix_message.h |
Message construction with auto-computed BodyLength and CheckSum |
| FIXSession | include/fix/fix_session.h |
Session-layer state machine: logon, heartbeat, sequence management, gap recovery |
| FIXEngine | include/fix/fix_engine.h |
TCP transport with dual-thread I/O model (acceptor and initiator modes) |
| CounterpartySimulator | include/fix/counterparty_simulator.h |
Mock exchange that processes orders and sends execution reports |
| FIX Constants | include/fix/fix_constants.h |
Protocol constants: tag numbers, message types, field values, version strings |
fix-engine/
├── CMakeLists.txt # Build configuration (CMake 3.16+)
├── include/fix/ # Public headers
│ ├── fix_constants.h # FIX tags, message types, enumerations
│ ├── fix_parser.h # Zero-allocation parser interface
│ ├── fix_message.h # Message builder (header-only)
│ ├── fix_session.h # Session state machine
│ ├── fix_engine.h # TCP transport layer
│ └── counterparty_simulator.h # Exchange simulator
├── src/ # Implementation
│ ├── fix_parser.cpp # Parser: tag=value|SOH parsing, checksum
│ ├── fix_message.cpp # Builder stub (mostly header-only)
│ ├── fix_session.cpp # Session: ~530 lines of state management
│ ├── fix_engine.cpp # Transport: socket I/O, threading
│ ├── counterparty_simulator.cpp # Simulator: order handling, exec reports
│ ├── client_main.cpp # Client application entry point
│ └── simulator_main.cpp # Simulator application entry point
├── test/ # Unit tests
│ ├── test_main.cpp # Test runner
│ ├── test_parser.cpp # Parser tests
│ └── test_session.cpp # Session tests
└── bench/ # Performance benchmarks
└── bench_parser.cpp # Latency and throughput measurements
- C++17 compatible compiler (GCC 7+, Clang 5+, Apple Clang 10+)
- CMake 3.16 or later
- POSIX-compliant OS (Linux, macOS)
mkdir -p build && cd build
cmake ..
makeThis produces:
| Target | Binary | Description |
|---|---|---|
libfix_core.a |
Static library | Core FIX engine (parser, session, transport) |
fix_tests |
Executable | Unit test suite |
fix_bench |
Executable | Performance benchmarks |
fix_client |
Executable | Demo FIX client (order sender) |
fix_simulator |
Executable | Demo counterparty (mock exchange) |
Compilation flags: -O3 -DNDEBUG -march=native for maximum performance.
Start the counterparty simulator (acceptor) in one terminal:
./build/fix_simulator [port]
# Default port: 9876Connect with the client (initiator) in another terminal:
./build/fix_client [host] [port] [num_orders]
# Default: localhost 9876 5The client performs a complete FIX session lifecycle:
- Establishes TCP connection and sends Logon
- Sends NewOrderSingle messages
- Sends OrderCancelRequest and OrderCancelReplaceRequest
- Receives ExecutionReports (New, Fill, Cancelled, Replaced)
- Initiates graceful Logout
./build/fix_testsTests cover:
- Parser: Roundtrip build-parse-verify for all message types, checksum validation, stream fragmentation handling
- Session: Logon/logout handshake (initiator and acceptor), heartbeat response, ResendRequest generation and handling, gap-fill sequencing, duplicate detection
./build/fix_benchMeasures:
- Parse latency: min, avg, median, p99, p99.9, max (nanoseconds) over 100K iterations
- Message types: NewOrderSingle and ExecutionReport
- Round-trip: Build + parse + field extraction
- Sustained throughput: 1M consecutive messages, reported in messages/second
The parser (FIXParser::parse()) is the performance-critical hot path:
- Zero heap allocations: Uses a stack-allocated
ParsedMessagewith a fixed array of 64FieldViewentries - Zero-copy field access:
FieldViewstoresstd::string_viewreferences into the original buffer - Fast numeric conversion: Custom
fast_atoi()andfast_atof()bypass locale-aware stdlib functions - Stream-safe: Returns bytes consumed, handles partial messages across TCP reads
- Checksum validation: Computes running sum mod 256 over the message body
struct FieldView {
int tag;
std::string_view value;
};
struct ParsedMessage {
FieldView fields[64]; // Stack-allocated, no heap
size_t field_count = 0;
// Quick-access extracted headers
std::string_view begin_string, msg_type, sender_comp_id, target_comp_id;
int msg_seq_num = 0;
};DISCONNECTED ──logon──► LOGON_SENT ──ack──► ACTIVE ──logout──► LOGOUT_SENT ──ack──► DISCONNECTED
│ ▲
gap detected gap filled
▼ │
RESENDING
- Heartbeat interval: 30 seconds (configurable via
SessionConfig) - TestRequest: Sent if no data received within heartbeat interval + 5 seconds
- Gap recovery: Detects sequence gaps, sends ResendRequest, queues out-of-order messages, delivers in sequence after gap fill
- Message store: Retains sent messages (keyed by sequence number) for resend support
- Dual-thread model: Dedicated I/O thread (poll-based socket reads) and timer thread (1-second tick)
- TCP_NODELAY: Nagle's algorithm disabled for minimal write latency
- SO_REUSEADDR: Enables rapid socket reuse during development/restart
- Buffer size: 8 KB stack-allocated read buffer per I/O cycle
The FIXMessageBuilder constructs outbound FIX messages:
- Sets standard headers (BeginString, BodyLength, MsgType, SenderCompID, TargetCompID, MsgSeqNum, SendingTime)
- Supports typed field addition:
add_field(tag, int),add_field(tag, double),add_field(tag, char),add_field(tag, string) - Auto-computes BodyLength and CheckSum on
build() - Uses heap allocation (acceptable for outbound path, which is not latency-critical)
| Feature | Support |
|---|---|
| Versions | FIX 4.2, FIX 4.4 |
| Message format | Tag=Value|SOH (standard FIX encoding) |
| Admin messages | Logon (A), Logout (5), Heartbeat (0), TestRequest (1), ResendRequest (2), SequenceReset (4), Reject (3) |
| App messages | NewOrderSingle (D), ExecutionReport (8), OrderCancelRequest (F), OrderCancelReplaceRequest (G) |
| Checksum | Computed and validated (sum of bytes mod 256) |
| Sequence numbers | Full management with gap detection, resend, and reset |
| Metric | Expected Range |
|---|---|
| Parse latency (avg) | < 1 microsecond |
| Parse latency (p99) | Low single-digit microseconds |
| Throughput | Millions of messages/second |
| Memory (parser) | Zero heap allocations per message |
| Memory (session) | O(stored messages) for resend support |
Benchmarked with -O3 -march=native on modern x86_64 hardware.
| Layer | Technology |
|---|---|
| Language | C++17 |
| Build System | CMake 3.16+ |
| Networking | POSIX TCP sockets, poll() |
| Threading | std::thread, std::atomic |
| Dependencies | None (C++ standard library only) |
| Platform | Unix-like (Linux, macOS) |
All rights reserved.