FIX Protocol Parser

MEDIUM • Live C++ Rust Java Python
1M
MESSAGES
50+
TAG TYPES
8
MSG TYPES

Problem Description

Parse 1,000,000 FIX 4.2 protocol messages, validate fields, and extract key order data. Handle multiple message types including NewOrderSingle, ExecutionReport, OrderCancelRequest, and others. Validate field presence, data types, and checksums.

Output summary statistics: total messages, valid/invalid counts, message type distribution, and extracted order data aggregates.

Tier System & Performance Targets

LANGUAGEGOLDSILVERBRONZE
C++ / Rust< 300ms< 1000ms< 5000ms
Java< 600ms< 2000ms< 10000ms
Python< 2000ms< 5000ms< 30000ms

Evaluation Criteria

Correctness: 12 output lines are compared against the reference. Integer lines must match exactly. Float values (VWAP) use tolerance. String values must match exactly.

Performance: Wall-clock time to parse all messages determines tier placement.

Input Format

Read from stdin. The first line is the number of messages N. The next N lines are FIX-format messages with pipe (|) delimiters:

8=FIX.4.2|35=D|49=SENDER|56=TARGET|11=ORD001|55=AAPL|54=1|38=100|44=150.00|10=100|

Key FIX tags:

Output Format

Output exactly 12 lines to stdout (plain values, one per line):

TOTAL_MESSAGES
UNIQUE_ORDERS
FULLY_FILLED
PARTIALLY_FILLED
CANCELED
REJECTED
TOTAL_BUY
TOTAL_SELL
TOTAL_FILLED_QTY
VWAP
UNIQUE_SYMBOLS
SYMBOL_MAX

Where:

Example

Input

3
8=FIX.4.2|35=D|49=CLIENT1|56=BROKER|11=ORD001|55=AAPL|54=1|38=100|44=150.00|10=100|
8=FIX.4.2|35=8|49=BROKER|56=CLIENT1|11=ORD001|55=AAPL|54=1|38=100|44=150.00|39=2|32=100|31=150.00|10=101|
8=FIX.4.2|35=D|49=CLIENT2|56=BROKER|11=ORD002|55=MSFT|54=2|38=50|44=300.50|10=102|

Output

3
2
1
0
0
0
1
1
100
150.000000
2
AAPL

12 plain values: total messages, unique orders, fully filled, partially filled, canceled, rejected, buy count, sell count, filled qty, VWAP, unique symbols, top symbol by filled qty.

Submission Rules

Starter Templates

C++
#include <cstdio>
#include <cstring>
#include <unordered_map>

struct FIXMessage {
    char begin_string[20];
    int body_length;
    char msg_type[4];
    char sender[20];
    char target[20];
    char symbol[10];
    char side;
    int order_qty;
    double price;
    char checksum[10];
};

int main() {
    // Read FIX messages from stdin
    // Parse and validate each message
    // Track statistics
    // Output summary
    return 0;
}
Python
import sys
from collections import defaultdict

def parse_fix_message(line):
    # Replace SOH with pipe or parse directly
    fields = line.split('|')
    message = {}
    for field in fields:
        if '=' in field:
            tag, value = field.split('=', 1)
            message[tag] = value
    return message

stats = {
    'total': 0,
    'valid': 0,
    'invalid': 0,
    'msg_types': defaultdict(int),
    'total_qty': 0,
    'total_value': 0.0
}

for line in sys.stdin:
    msg = parse_fix_message(line.strip())
    stats['total'] += 1

    # Validate message
    # Extract order data
    # Update statistics

# Output stats
Rust
use std::io::{self, BufRead};
use std::collections::HashMap;

struct FIXMessage {
    fields: HashMap<String, String>,
}

fn parse_fix_message(line: &str) -> FIXMessage {
    let mut fields = HashMap::new();
    for part in line.split('|') {
        if let Some(pos) = part.find('=') {
            let (tag, value) = part.split_at(pos);
            fields.insert(tag.to_string(), value[1..].to_string());
        }
    }
    FIXMessage { fields }
}

fn main() {
    let stdin = io::stdin();
    let mut total = 0;
    let mut valid = 0;

    for line in stdin.lock().lines() {
        if let Ok(line) = line {
            let msg = parse_fix_message(&line);
            total += 1;
            // Validate and extract data
        }
    }
}
Java
import java.util.*;
import java.io.*;

public class Solution {
    static class FIXMessage {
        Map<String, String> fields = new HashMap<>();
    }

    static FIXMessage parseMessage(String line) {
        FIXMessage msg = new FIXMessage();
        String[] parts = line.split("\\|");
        for (String part : parts) {
            String[] kv = part.split("=", 2);
            if (kv.length == 2) {
                msg.fields.put(kv[0], kv[1]);
            }
        }
        return msg;
    }

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int total = 0, valid = 0;
        Map<String, Integer> msgTypes = new HashMap<>();

        String line;
        while ((line = br.readLine()) != null) {
            FIXMessage msg = parseMessage(line);
            total++;
            // Validate and extract data
        }
    }
}

Submit Your Solution

Supported formats: .cpp, .py, .rs, .java, or raw text