FIX 4.4 Connection Guide
Comprehensive guide to FIX protocol connections, message debugging, and real-world best practices
0. Note
We recommend using the Python client package — it handles all FIX protocol details for you, so you can start papertrading in minutes without reading this guide.
Only come back here if you need to debug at the protocol level or want a deeper understanding of how FIX works under the hood.
1. Connection Prerequisites
Before connecting to FIX, ensure you have all the following information ready:
Account Information
| Field | Description | Example |
|---|---|---|
| username | Paper Broker login username | your_username |
| password | Account password | your_password |
| default_sub_account | Default sub-account for trading | D1, D2, D3... |
FIX Session Information
| Field | Description | Example |
|---|---|---|
| sender_comp_id | Client identifier (your ID) | TRADER-001-FIX |
| target_comp_id | Server identifier | PAPERBROKER |
| socket_connect_host | FIX server address | localhost / 192.168.1.100 |
| socket_connect_port | FIX server port | 5001 |
REST API (Optional)
| Field | Description | Example |
|---|---|---|
| rest_base_url | REST API base URL | http://localhost:9090 |
sender_comp_id must be unique for each client. If two clients use the same sender_comp_id,
the session will conflict and connection will fail.
2. Configuration File Setup
QuickFIX uses a configuration file (.cfg) to define session parameters. Below is a detailed breakdown of each setting:
Sample Configuration File
Configuration Parameters Explained
[DEFAULT] Section
| Parameter | Description | Recommended Value |
|---|---|---|
| ConnectionType | Client role: initiator (client connects to server) or acceptor (server waits for connections) |
initiator |
| SocketConnectHost | IP address or hostname of FIX server | Your server IP |
| SocketConnectPort | TCP port for FIX connection | 5001 (or server-specified) |
| StartTime | Time when session becomes active (UTC) | 00:00:00 |
| EndTime | Time when session ends (UTC) | 23:59:59 |
| HeartBtInt | Heartbeat interval in seconds. If no message exchanged within this time, heartbeat is sent | 30 |
| FileStorePath | Directory to store sequence numbers and message history | logs/fix/store/ |
| FileLogPath | Directory for FIX message logs | logs/fix/ |
[SESSION] Section
| Parameter | Description | Recommended Value |
|---|---|---|
| BeginString | FIX protocol version | FIX.4.4 |
| SenderCompID | Your unique client identifier | Assigned by server admin |
| TargetCompID | Server identifier | Provided by server |
| DataDictionary | Path to FIX data dictionary XML file | /path/to/FIX44.xml |
| ResetOnLogon | Reset sequence numbers on each logon | Y |
| ResetOnLogout | Reset sequence numbers on logout | Y |
| ResetOnDisconnect | Reset sequence numbers on disconnect | Y |
DataDictionary - Why It's Critical
The DataDictionary (FIX44.xml) defines:
- Message Structure: Which tags are required, optional, or forbidden for each message type
- Field Validation: Valid values for each tag (e.g., Side: 1=Buy, 2=Sell)
- Custom Fields: Any server-specific tags beyond standard FIX 4.4
- Group Definitions: Repeating groups structure
- Missing dictionary: Messages rejected with "Invalid tag" errors
- Wrong version: Using FIX42.xml for FIX 4.4 session causes validation failures
- Custom fields not defined: Server-specific tags will be rejected
Solution: Always request the exact DataDictionary file from your server administrator.
Optional Validation Settings
| Parameter | Description | When to Use |
|---|---|---|
| ValidateFieldsOutOfOrder=N | Don't reject messages with tags in wrong order | When server sends non-standard tag order |
| ValidateUserDefinedFields=N | Don't validate custom tags (5000+) | When server uses custom fields not in dictionary |
| IgnoreSeqNumTooLow=Y | Accept messages with lower-than-expected sequence | During development/testing |
2. Connection Sequence
FIX connection follows a strict sequence. Understanding this sequence helps you debug connection issues.
Connection Flow
Actual Timeline
4. Message Flow
Each action you perform triggers a chain of messages. Below are the most common flows:
The intermediate states (PendingNew, PendingCancel) are server design decisions. Some servers send these states, others skip directly to New/Canceled. Always check your server's documentation or test to understand which execution reports you'll receive.
Place Order Flow (Full)
Cancel Order Flow (Full)
Market Data Flow
ExecType (150) State Reference
| Value | ExecType | Description | Server Optional? |
|---|---|---|---|
| A | Pending New | Order received, not yet accepted | Yes - many servers skip this |
| 0 | New | Order accepted and active | No - always sent |
| 1 | Partial Fill | Order partially executed | No |
| 2 or F | Fill | Order fully executed | No |
| 6 | Pending Cancel | Cancel request received, not yet processed | Yes - many servers skip this |
| 4 | Canceled | Order successfully canceled | No |
| 8 | Rejected | Order rejected | No |
5. OrderID vs ClOrdID - Critical Difference
Understanding the difference between OrderID and ClOrdID is crucial to avoid ID mismatch errors, especially in cancel/modify flows.
Confusing ClOrdID with OrderID, or using the wrong OrigClOrdID, is the #1 cause of "Order not found" or "Unknown order" rejections.
ID Definitions
| Tag | Name | Who Creates It | Purpose |
|---|---|---|---|
| 11 | ClOrdID | Client | Your unique identifier for each request. Must be unique per session. |
| 37 | OrderID | Server | Server's internal order identifier. Returned in ExecutionReports. |
| 41 | OrigClOrdID | Client | Used in Cancel/Modify requests to reference the original order's ClOrdID. |
ID Flow Example
Common ID Mistakes
Each request (order, cancel, modify) must have a unique ClOrdID.
OrigClOrdID (41) must be the ClOrdID you sent, not the server's OrderID.
Some servers require OrderID (37) in cancel requests. If you don't store it from the ExecutionReport, your cancel will fail.
Best Practice: ID Management
- ClOrdID format:
{prefix}-{timestamp}-{counter}(e.g., ORD-20260212093000-001) - Always unique: Never reuse ClOrdID within a session
- Store mapping: Keep a map of ClOrdID → OrderID from ExecutionReports
- Cancel/Modify: Generate new ClOrdID, use stored original as OrigClOrdID
6. Reading FIX Messages
FIX messages have a special format: Tag=Value separated by SOH (ASCII 01).
In log files, SOH is typically displayed as | or ^A.
FIX Message Structure
Field Breakdown:
| Tag | Name | Value | Meaning |
|---|---|---|---|
| 8 | BeginString | FIX.4.4 | FIX protocol version |
| 9 | BodyLength | 148 | Message body length |
| 35 | MsgType | D | NewOrderSingle (new order) |
| 49 | SenderCompID | CLIENT-FIX | Sender identifier |
| 56 | TargetCompID | SERVER | Receiver identifier |
| 34 | MsgSeqNum | 2 | Message sequence number |
| 11 | ClOrdID | ORD001 | Client Order ID (you generate this) |
| 55 | Symbol | VNM | Stock symbol |
| 54 | Side | 1 | 1=Buy, 2=Sell |
| 38 | OrderQty | 100 | Quantity |
| 40 | OrdType | 2 | 2=Limit order |
| 44 | Price | 85000 | Order price |
| 10 | CheckSum | 123 | Checksum for message verification |
Always read 35= (MsgType) first to identify the message type. Then check the relevant tags based on that type.
7. Important Debug Fields
When debugging FIX messages, focus on these key tags:
Tag 35 - MsgType (Message Type)
| Value | Name | Description |
|---|---|---|
| A | Logon | Session login |
| 0 | Heartbeat | Keep-alive message |
| 5 | Logout | Session logout |
| D | NewOrderSingle | New order placement |
| F | OrderCancelRequest | Order cancellation request |
| G | OrderCancelReplaceRequest | Order modification |
| 8 | ExecutionReport | Order execution result |
| 9 | OrderCancelReject | Cancel request rejected |
| 3 | Reject | Message rejected (format error) |
| V | MarketDataRequest | Market data request |
| W | MarketDataSnapshot | Market data response |
Tag 39 - OrdStatus (Order Status)
| Value | Status | Description |
|---|---|---|
| 0 | New | New order accepted |
| 1 | Partially Filled | Partially filled |
| 2 | Filled | Fully filled |
| 4 | Canceled | Order canceled |
| 8 | Rejected | Order rejected |
Tag 150 - ExecType (Execution Type)
| Value | Type | Description |
|---|---|---|
| 0 | New | New order created |
| 1 | Partial Fill | Partially filled |
| 2 or F | Fill | Fully filled |
| 4 | Canceled | Successfully canceled |
| 8 | Rejected | Order rejected |
Tag 58 - Text (Error Message)
When you receive a Reject (35=3) or ExecutionReport with Rejected status, always read tag 58 for the detailed reason.
8. Common Issues & Solutions
Symptoms: Sudden disconnection, no heartbeat response received
Causes:
- Not sending heartbeat at correct interval (default 30s)
- Network issue / Firewall block
- Server overload
Solutions:
- Check HeartBtInt setting (tag 108 in Logon)
- Implement reconnect logic with exponential backoff
- Check firewall rules for FIX port
Symptoms: Receiving ResendRequest (35=2) or SequenceReset (35=4)
Causes:
- Client restart without sequence reset
- Messages lost during transmission
- Sequence file corrupted
Solutions:
- Send Logon with ResetSeqNumFlag=Y (tag 141=Y)
- Delete sequence files and reconnect
- Check message store configuration
Symptoms: ExecutionReport with 39=8 (Rejected)
Common causes:
58=Insufficient funds- Not enough cash58=Invalid symbol- Invalid stock symbol58=Price out of range- Price outside allowed range58=Quantity invalid- Invalid quantity (must be divisible by lot size)58=Market closed- Market is closed
Solution: Read tag 58 carefully for the specific reason
Symptoms: MsgType=3 with SessionRejectReason
Causes:
- Tag 373=1: Invalid tag number
- Tag 373=5: Value incorrect for tag
- Tag 373=9: CompID problem
- Tag 373=11: Invalid MsgType
Solutions:
- Check RefSeqNum (tag 45) to identify which message was rejected
- Check RefTagID (tag 371) to identify which tag has problem
- Verify message format against FIX 4.4 spec
9. Experience & Best Practices
- Log ALL messages: Both outgoing and incoming
- Timestamp: Include microseconds to debug timing issues
- Pretty print: Convert SOH → | for readability in logs
- Separate log files: Keep FIX messages separate from application logs
- Wait for Logon: Always wait for Logon response before sending orders
- Retry with backoff: 1s → 2s → 4s → 8s → max 30s
- Health check: Monitor heartbeat response time
- Graceful shutdown: Send Logout (35=5) before disconnecting
- Unique: Use UUID or timestamp-based ID
- Traceable: Include prefix for easy log searching
- No reuse: Each order must have a different ClOrdID
- Always check OrdStatus: Don't assume order success
- Handle partial fills: Track CumQty and LeavesQty
- Timeout handling: Set timeout for each order, cancel if expired
- Idempotency: Implement to handle duplicate responses
When debugging, build a simple tool to parse FIX messages into readable format. This will save significant time when handling production issues.