A FIX testing daemon that simulates Coinbase Prime's FIX gateway for local development and testing.
A local testing tool that mimics Coinbase Prime's FIX API responses. Use it to develop and test FIX clients without connecting to production.
Simulates:
- Session management (Logon, Logout, Heartbeat, TestRequest, SequenceReset)
- Order entry (NewOrderSingle, OrderCancelRequest, OrderStatusRequest)
- Execution reports (fills, partial fills, cancellations, rejections)
- Market data snapshots (trades, order book, OHLCV)
- RFQ (Request for Quote)
- DropCopy sessions (read-only execution report streaming)
Does NOT provide:
- Real authentication (HMAC signatures are not validated)
- Real order execution (orders are simulated)
- Persistent state (everything is in-memory)
- Production parity (responses approximate but may differ from actual Prime)
Production-like behaviors:
- Rate limiting (50 requests/second per session)
- Proper FIX sequence number handling with message queuing during gaps
- Graceful cleanup of subscriptions on disconnect
- Thread-safe session and market data management
go build -o prime-fix-daemon ./cmd/daemon
go build -o fix-testclient ./cmd/testclient# Terminal 1: Start daemon
./prime-fix-daemon
# Terminal 2: Start test client
./fix-testclientThe test client (fix-testclient) provides an interactive REPL for testing FIX functionality. All commands are documented below.
| Command | Description |
|---|---|
buy <symbol> <qty> [base|quote] |
Market buy order. Default is quote quantity (USD amount) |
sell <symbol> <qty> [base|quote] |
Market sell order. Default is quote quantity (USD amount) |
market <symbol> <buy|sell> <base|quote> <qty> |
Explicit market order with quantity type |
limit <symbol> <buy|sell> <qty> <price> |
Limit order at specified price |
Examples:
buy BTC-USD 100 # Buy $100 worth of BTC (quote quantity)
buy BTC-USD 0.001 base # Buy exactly 0.001 BTC (base quantity)
sell ETH-USD 500 # Sell $500 worth of ETH
sell ETH-USD 0.5 base # Sell exactly 0.5 ETH
market BTC-USD buy quote 1000 # Buy $1000 of BTC (explicit syntax)
market ETH-USD sell base 2.0 # Sell 2.0 ETH (explicit syntax)
limit BTC-USD buy 0.01 85000 # Limit buy 0.01 BTC @ $85,000
limit ETH-USD sell 1.0 4000 # Limit sell 1.0 ETH @ $4,000| Command | Description |
|---|---|
status <orderid|clordid> |
Query order status by OrderID or ClOrdID |
cancel <orderid> <origclordid> <symbol> <side> <qty> |
Cancel an open order |
Examples:
status abc123-def456 # Get status of order
cancel abc123 orig123 BTC-USD buy 0.01 # Cancel order| Command | Description |
|---|---|
rfq <symbol> <buy|sell> <qty> <limit_price> |
Request a quote for a specified quantity |
Examples:
rfq BTC-USD buy 0.5 90000 # Request quote to buy 0.5 BTC with limit $90,000
rfq ETH-USD sell 10 3500 # Request quote to sell 10 ETH with limit $3,500| Command | Alias | Description |
|---|---|---|
md <symbol> [trades|book|ohlcv] |
- | Get market data snapshot (default: trades) |
subscribe <symbol> [trades] |
sub |
Subscribe to streaming market data |
unsubscribe <symbol> |
unsub |
Stop streaming market data |
Examples:
md BTC-USD # Trade snapshot (default)
md BTC-USD trades # Trade snapshot (explicit)
md BTC-USD book # Order book snapshot (bids/offers)
md BTC-USD ohlcv # OHLCV candle data (100 daily candles)
subscribe BTC-USD trades # Start streaming trades (MsgType=X)
sub ETH-USD trades # Alias for subscribe
unsubscribe BTC-USD # Stop streaming
unsub ETH-USD # Alias for unsubscribeThese commands change daemon behavior at runtime without restarting.
| Command | Alias | Description |
|---|---|---|
config |
get-config |
Display current daemon configuration |
set-behavior <behavior> |
behavior |
Set default behavior for all orders |
set-symbol <symbol> <behavior> |
- | Set behavior for a specific symbol |
clear-symbol <symbol> |
- | Remove symbol-specific behavior (use default) |
Behavior values: fill, partial, cancel, pending, reject
Examples:
config # Show current configuration
set-behavior reject # All orders will be rejected
behavior fill # Alias: all orders will fill
set-symbol BTC-USD partial # BTC orders partially fill
set-symbol ETH-USD reject # ETH orders rejected
clear-symbol BTC-USD # BTC uses default behavior again| Command | Alias | Description |
|---|---|---|
heartbeat |
hb |
Send a heartbeat message |
logout |
- | Send logout and disconnect gracefully |
quit |
exit |
Send logout and exit the client |
help |
? |
Display command help |
Examples:
heartbeat # Send heartbeat
hb # Alias for heartbeat
logout # Graceful disconnect
quit # Exit client
help # Show all commands
? # Alias for help| Behavior | Description |
|---|---|
fill |
Order immediately fills completely |
partial |
Order partially fills in multiple executions |
cancel |
Order is accepted then canceled |
pending |
Order stays in pending/new state indefinitely |
reject |
Order is rejected immediately |
# Start the daemon (default settings)
./prime-fix-daemon
# Show help
./prime-fix-daemon --help
# Show version
./prime-fix-daemon --version
# Generate example config
./prime-fix-daemon generate-config
# Available flags:
# -l, --listen string Listen address (default ":4198")
# -b, --behavior string Default order behavior: fill, partial, cancel, pending, reject (default "fill")
# -c, --config string Path to configuration file
# --heartbeat int Heartbeat interval in seconds (default 30)
# --tls Enable TLS
# --tls-cert string TLS certificate file
# --tls-key string TLS key file
# --reject-auth Always reject authentication (for testing auth failures)
# Examples:
./prime-fix-daemon -l :5000 -b reject # Custom port, reject all orders
./prime-fix-daemon -c config.json # Use config file
./prime-fix-daemon --tls --tls-cert cert.pem --tls-key key.pem# Connect to default address (127.0.0.1:4198)
./fix-testclient
# Connect to custom address
./fix-testclient -a localhost:5000
./fix-testclient --addr 192.168.1.100:4198
# Show help
./fix-testclient --helpexport FIX_FILL_SYMBOLS=BTC-USD,ETH-USD
export FIX_PARTIAL_SYMBOLS=SOL-USD
export FIX_CANCEL_SYMBOLS=DOGE-USD
export FIX_REJECT_SYMBOLS=SHIB-USD./prime-fix-daemon generate-config # Creates config.json
./prime-fix-daemon -c config.json # Use config fileOnly these symbols are accepted for orders, RFQ, and market data:
| Symbol | Simulated Price |
|---|---|
| BTC-USD | $90,000 |
| ETH-USD | $3,500 |
| SOL-USD | $200 |
| DOGE-USD | $0.40 |
| XRP-USD | $2.20 |
| ADA-USD | $0.90 |
| AVAX-USD | $40 |
| LINK-USD | $23 |
Requests for unsupported symbols are rejected with a BusinessReject (orders/RFQ) or MarketDataReject (market data).
- Version: FIX 4.2
- Server SenderCompID: COIN
- Default Port: 4198
- Heartbeat: 30 seconds
| MsgType | Name | Direction |
|---|---|---|
| A | Logon | Both |
| 5 | Logout | Both |
| 0 | Heartbeat | Both |
| 1 | TestRequest | Both |
| 2 | ResendRequest | Client → Server |
| 4 | SequenceReset | Server → Client |
| D | NewOrderSingle | Client → Server |
| F | OrderCancelRequest | Client → Server |
| H | OrderStatusRequest | Client → Server |
| R | QuoteRequest (RFQ) | Client → Server |
| S | Quote | Server → Client |
| V | MarketDataRequest | Client → Server |
| W | MarketDataSnapshot | Server → Client |
| X | MarketDataIncremental | Server → Client |
| 8 | ExecutionReport | Server → Client |
| 9 | OrderCancelReject | Server → Client |
| BE | UserRequest (Control) | Client → Server |
| BF | UserResponse (Control) | Server → Client |
Configure your client to connect to localhost:4198:
[SESSION]
BeginString=FIX.4.2
SenderCompID=3e74e5c7-56a1-556a-b044-19936c5a728a
TargetCompID=COIN
SocketConnectHost=127.0.0.1
SocketConnectPort=4198
HeartBtInt=30SenderCompID: This is your Service Account ID (a UUID) from Coinbase Prime. You can find it in the Prime web console under Settings > API. In production, each API key is tied to a specific portfolio and the SenderCompID identifies your session.
Note: This testing daemon does not validate authentication, so any UUID-formatted SenderCompID will work for local testing.
The daemon supports DropCopy sessions for testing clients that use separate order entry and execution report streaming connections. Up to 7 concurrent FIX sessions are supported.
How it works:
- A session becomes a DropCopy session when it sends
DropCopyFlag=Y(tag 9406) in the Logon message - DropCopy sessions receive copies of all execution reports from other sessions
- DropCopy sessions cannot submit orders or cancellations (rejected with BusinessReject)
Example Logon with DropCopy flag:
8=FIX.4.2|9=...|35=A|49=CLIENT|56=COIN|...|9406=Y|...