FIX Protocol Parser
Hard ● Live C++ Rust Java PythonThe Problem
Parse 1,000,000 FIX (Financial Information eXchange) protocol messages from a binary stream. Reconstruct the complete order flow by correlating executionReports with original orders. Compute fill statistics per symbol and per trader.
The FIX protocol is the industry standard for electronic financial trading communication. Optimize for speed and correctness on real-world message volume.
Evaluation Criteria
Correctness (70%)
All orders parsed and matched correctly. Fill statistics must match reference implementation exactly.
Performance (30%)
Wall-clock time on 1M FIX messages. Memory usage (peak RSS).
Message Types
NewOrderSingle (D)
Initiates a new trade order. Key fields: ClOrdID, Symbol, OrderQty, Price, Side (1=Buy, 2=Sell).
ExecutionReport (8)
Reports order executions and status changes. Fields: ClOrdID, LastQty, LastPx, OrdStatus (0=New, 1=Partial, 2=Filled, 4=Cancelled).
OrderCancelRequest (F)
Requests order cancellation. Fields: ClOrdID, OrigClOrdID.
Input Format
- Each line
- one FIX 4.2 message, with
|as the field separator (replacing the standard SOH character). - Common tags
8=BeginString,35=MsgType,49=SenderCompID,56=TargetCompID,11=ClOrdID,55=Symbol,54=Side,38=OrderQty,44=Price,10=Checksum.- Message types
D=NewOrderSingle,8=ExecutionReport,F=OrderCancelRequest.
Output Format & Sample
Sample input (first 8 lines, full file linked below):
30 8=FIX.4.2|35=D|49=SENDER|56=TARGET|11=ORD0000001|55=BAC|54=1|38=238|44=32.79|10=100| 8=FIX.4.2|35=D|49=SENDER|56=TARGET|11=ORD0000002|55=AMD|54=1|38=614|44=133.75|10=101| 8=FIX.4.2|35=D|49=SENDER|56=TARGET|11=ORD0000003|55=NVDA|54=1|38=527|44=701.01|10=102| 8=FIX.4.2|35=8|11=ORD0000003|150=1|14=430|151=97|31=693.17|32=430|10=103| 8=FIX.4.2|35=8|11=ORD0000001|150=1|14=41|151=197|31=33.05|32=41|10=104| 8=FIX.4.2|35=8|11=ORD0000001|150=1|14=97|151=141|31=33.39|32=56|10=105| 8=FIX.4.2|35=8|11=ORD0000001|150=1|14=195|151=43|31=32.26|32=98|10=106| ... (more)
Expected output for that sample (first 8 lines):
30 11 0 8 0 0 8 3 ... (more)
↓ download full sample input | ↓ download expected output
Test your solution locally:
./your_solution < input.txt | diff - output.txt
Common Pitfalls
- Parse 1,000,000 messages fast. Don't use regex; split on
|then split each field on=. C++/Rust submissions doing regex won't hit Gold. - Validate the checksum (tag 10). Sum of all bytes before the checksum tag, mod 256. The grader expects you to count valid vs invalid checksums in the summary.
- Output: total messages, valid count, invalid count, then message-type distribution and per-symbol stats. Format details in the sample output.
- Don't allocate a string per field. Use string_view (C++17) or slices (Rust). Field-level allocation is the biggest performance pitfall.
- Tags can appear in any order within a message. Don't assume tag 35 always comes second.
Performance Tier Thresholds (applied by the grader)
| Language | Gold | Silver | Bronze | Tier 4 |
|---|---|---|---|---|
| C++ | <300ms | <1000ms | <5000ms | else PASS |
| Rust | <300ms | <1000ms | <5000ms | else PASS |
| Java | <800ms | <3000ms | <10000ms | else PASS |
| Python | <2000ms | <5000ms | <20000ms | else PASS |
Submission Rules
- Single-file solutions only. All code must be in one file.
- Your program must read from stdin and write to stdout.
- Java class must be named Solution.
- No network access, no filesystem access beyond stdin/stdout.
- Time limit: 120 seconds. Memory limit: 2 GB.