QuantReplay Engine: Open-Source Trading Simulator by Quod Financial

Monika KucharskaNews, Press

Quod Financial Releases QuantReplay: Open-Source Simulator for Multi-Asset Strategy Testing

Quod Financial Releases QuantReplay: Open-Source Simulator for Multi-Asset Strategy Testing

QuantReplay is Quod Financial’s open-source, multi-asset market simulator: a self-hosted, order-driven exchange environment with a full matching engine, a QuickFIX-based FIX acceptor, market data publishing and configurable order flow. Originally built for Quod Financial’s internal strategy validation and released to the public in July 2025, it is now freely available under the Apache 2.0 license on GitHub.

This guide covers everything you need to deploy and configure the QuantReplay engine: the GitHub repository and installation options, the configSim.txt QuickFIX configuration file, the Docker Compose setup, port mapping (9050 and 9051), the REST API, and the Liquibase database migrations. It was last updated in July 2026 and verified against the current main branch of the repository.

What is the QuantReplay Engine?

The QuantReplay engine is an open-source market simulator suite that lets you create realistic, order-driven trading venues on your own infrastructure. Each simulated venue runs as a single native C++ process, backed by a shared PostgreSQL database, and exposes two interfaces: a FIX API for trading and market data (via a QuickFIX acceptor) and a REST API for remote administration.

Core capabilities of the engine include:

  • Matching engine — standard price/time priority order book logic, with support for multiple order types and time-in-force values.
  • Market data publishing — L2 market depth as full refresh or incremental updates at configurable depth levels, plus L1 details such as last trades and OHLC.
  • Random order generation — realistic pseudo-random order activity with configurable update rate, quantity and price ranges.
  • Historic data playback — replay of multi-level historical market data from a database or CSV file.
  • Market phases — continuous trading and configurable market phases, with auction phases on the public roadmap.
  • Recovery options — save and restore simulator state on demand for long-running test campaigns.

Because the simulator emulates any order-driven venue, it covers equities, FX, futures and derivatives, exchange-listed fixed income and digital assets. Quant developers use it for strategy backtesting, infrastructure teams use it for latency and market microstructure testing, and AI/ML teams use it as a training environment for execution models — the same environment Quod Financial’s own engineers use to validate order routing and execution logic before it reaches production.

GitHub Repository and Installation

The QuantReplay source code lives at github.com/Quod-Financial/quantreplay, maintained by Quod Financial under the Apache 2.0 license. The repository contains:

  • the C++ engine source (built with CMake 3.20+),
  • configuration templates in template/cfg/market_simulator.xml, configSim.txt and the FIX 5.0 SP2 / FIXT 1.1 data dictionaries,
  • the Liquibase database changelogs in db/,
  • and the source for the official documentation (REST API reference and FIX Rules of Engagement).

You do not need to build from source to get started. Quod Financial publishes prebuilt container images to the GitHub Container Registry (GHCR):

  • ghcr.io/quod-financial/deploy_marketsim — the QuantReplay engine itself,
  • ghcr.io/quod-financial/postgres_marketsim — a preconfigured PostgreSQL image,
  • ghcr.io/quod-financial/liquibase — the schema migration runner.

Image tags follow the repository branches: latest and main point to the latest stable build, develop tracks the development branch, and versioned tags such as v10 pin a specific release. For most users the recommended installation path is the Docker Compose quickstart described below. Full documentation is available on the official documentation site and the project wiki.

configSim.txt — Full Configuration Reference

configSim.txt (often written lowercase as configsim.txt) is the QuickFIX configuration file of the QuantReplay engine. It defines how the FIX acceptor behaves: which port it listens on, which FIX version and data dictionaries it uses, and the session identifiers your trading clients must present at logon.

Two configuration files work together, and it helps to know which one does what:

  • cfg/market_simulator.xml — the main configuration file of the engine. It sets the simulated venue ID (for example XETRA), the PostgreSQL connection (database simdb), logging, and HTTP options — and it points to the QuickFIX file through its <config> element.
  • cfg/configSim.txt — the QuickFIX session settings loaded by the engine at startup, in the standard QuickFIX INI format with one [DEFAULT] block and one or more [SESSION] blocks.

When you start QuantReplay with the official Docker Compose file, both files are generated automatically inside a cfg/ directory in your working folder on first run, so you can inspect and edit them without touching the repository.

SocketAcceptPort and Network Settings

The most searched-for setting in configSim.txt is SocketAcceptPort. In the official deployment template it is set to 9051 — the port your FIX clients (initiators) connect to. It must match the container port you map in docker-compose.yml. The key settings in the [DEFAULT] block are:

Setting Value in the official template What it does
ConnectionType acceptor QuantReplay accepts inbound FIX connections; your application is the initiator.
SocketAcceptPort 9051 TCP port of the FIX acceptor. Map it in Docker to reach it at localhost:9051.
SocketReuseAddress / SocketNodelay Y / Y Socket options for fast restarts and low-latency writes.
AppDataDictionary FIX50SP2_marketsimulator.xml Application-level dictionary — QuantReplay speaks FIX 5.0 SP2.
TransportDataDictionary FIXT11_marketsimulator.xml Transport-level dictionary for the FIXT 1.1 session layer.
StartTime / EndTime 00:00:00 / 00:00:00 A 24-hour FIX session with no scheduled disconnect.
HeartBtInt 30 Heartbeat interval in seconds.
ValidateUserDefinedFields / AllowUnknownMsgFields N / Y Lenient validation, so client apps with custom tags are not rejected.

Each [SESSION] block then defines one FIX session: BeginString=FIXT.1.1, the SenderCompID / TargetCompID pair, DefaultApplVerID=9 (FIX 5.0 SP2), message persistence and logon reset behaviour. You can declare several [SESSION] blocks — for example one for an order gateway and one for a market data feedhandler — each with its own CompID pair.

Full configSim.txt Example

This is the actual configSim.txt shipped in the official deployment template (template/cfg/configSim.txt in the repository), used by the Docker quickstart for the demo XETRA venue:

# cfg/configSim.txt — QuantReplay QuickFIX acceptor configuration
# Source: github.com/Quod-Financial/quantreplay (template/cfg/configSim.txt)

[DEFAULT]
ConnectionType=acceptor
SocketAcceptPort=9051
SocketReuseAddress=Y
SocketNodelay=Y
AppDataDictionary=/market-simulator/quod/data/cfg/default/FIX50SP2_marketsimulator.xml
TransportDataDictionary=/market-simulator/quod/data/cfg/default/FIXT11_marketsimulator.xml
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
ValidateUserDefinedFields=N
AllowUnknownMsgFields=Y

[SESSION]
BeginString=FIXT.1.1
SenderCompID=SIM_XETRA
TargetCompID=CLIENT_XETRA
DefaultApplVerID=9
PersistMessages=Y
FileStorePath=/market-simulator/quod/data/files_store_path_common
ResetOnLogon=Y
RefreshOnLogon=N

Note the direction of the identifiers: messages from the simulator carry SenderCompID=SIM_XETRA, so your client application must log on with SenderCompID=CLIENT_XETRA and TargetCompID=SIM_XETRA. A CompID mismatch is the most common cause of rejected logons.

QuickFIX Integration and Acceptor Setup

QuantReplay uses the open-source QuickFIX library as its FIX engine. The simulator always runs as a QuickFIX acceptor: it listens for inbound FIX connections on port 9051, and your trading application, gateway or feedhandler connects to it as an initiator. All acceptor behaviour is driven by configSim.txt, described above.

At the protocol level, QuantReplay uses the FIXT 1.1 session layer with FIX 5.0 SP2 application messages (DefaultApplVerID=9). Both data dictionaries ship in the cfg/default/ directory of the deployment, so you can extend or restrict fields without rebuilding the engine. Over a single acceptor port you can run separate sessions for order flow and market data by declaring multiple [SESSION] blocks.

A typical order round-trip against the demo venue looks like this: the client sends a NewOrderSingle (35=D) for an instrument such as VOW, and the simulator’s matching engine answers with an ExecutionReport (35=8) acknowledging the order as new (39=0), then reports fills, replacements (35=G) or cancellations (35=F) as they occur. Market data works the same way: a MarketDataRequest (35=V) returns a MarketDataSnapshotFullRefresh (35=W), either as a one-off snapshot or as a subscription with continuous full-refresh updates. The complete message set, supported tags and message flows are documented in the FIX Rules of Engagement.

Troubleshooting tip: QuickFIX session events — logons, logouts, heartbeats, reject reasons — are written to the engine logs. With the official Docker Compose setup the venue container is named after the instance (for example XETRA), so you can follow the FIX session live with:

docker logs -f XETRA

If a logon is rejected, check three things first: the CompID pair (see the note above), the BeginString (FIXT.1.1, not FIX.4.4), and that your client targets port 9051 — port 9050 is the REST API and will not answer FIX messages.

Docker Compose Setup

The fastest way to run the QuantReplay engine is Docker Compose. The official quickstart brings up three services: the simulator itself, a preconfigured PostgreSQL database, and a Liquibase container that prepares the schema and demo data before the engine starts.

  1. Create an empty directory.
  2. Create a docker-compose.yml file in it with the content below.
  3. Run docker compose up -d.
  4. On first start, a cfg/ directory is generated next to the file, containing market_simulator.xml, configSim.txt and the FIX dictionaries — edit these to customise your venue.
  5. The database is seeded with demo data: a XETRA venue and the instruments AMZ, MSF, NFC, VODI and VOW, so you can send orders immediately.

docker-compose.yml Example

This is the official quickstart Compose file from the repository README:

networks:
  market-simulator-net:
    driver: bridge

services:
  XETRA:
    image: ghcr.io/quod-financial/deploy_marketsim:latest
    container_name: XETRA
    networks:
      - market-simulator-net
    ports:
      - "9050:9050" # Port to send REST API requests
      - "9051:9051" # Port to send FIX messages
    volumes:
      - ./:/market-simulator/quod/data/
    environment:
      - INSTANCE_ID=XETRA
      - PREFIX=QUOD
    depends_on:
      liquibase:
        condition: service_completed_successfully

  database:
    image: ghcr.io/quod-financial/postgres_marketsim:latest
    container_name: market-simulator-database
    networks:
      - market-simulator-net
    ports:
      - 15432:5432
    volumes:
      - ./database_files:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=simdb
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready --user=postgres --dbname=simdb" ]
      retries: 2
      interval: 5s
      timeout: 10s

  liquibase:
    image: ghcr.io/quod-financial/liquibase:latest
    container_name: market-simulator-liquibase
    networks:
      - market-simulator-net
    depends_on:
      database:
        condition: service_healthy

The startup order is handled for you: the database must pass its health check before Liquibase runs, and the simulator only starts once Liquibase has completed successfully. To simulate several venues in parallel, add more engine services with distinct INSTANCE_ID values and unique host-side ports.

Port Mapping (9050 and 9051)

The QuantReplay engine exposes two ports, and keeping them straight saves a lot of debugging:

  • Port 9051 — FIX API. The QuickFIX acceptor. Point your trading clients at localhost:9051.
  • Port 9050 — REST API. The administration interface. Send HTTP requests to http://localhost:9050.

The quickstart also maps the PostgreSQL database to host port 15432, which is handy for inspecting the simdb schema with any SQL client. If 9050 or 9051 are already taken on your machine, change only the host side of the mapping (for example "19051:9051") — the container side must stay in sync with SocketAcceptPort in configSim.txt.

REST API: Managing QuantReplay on Port 9050

Alongside the FIX API on port 9051, the QuantReplay engine exposes a REST API on port 9050 for remote administration: listing and creating venues, managing instruments (listings), changing settings and checking simulator status. Responses are JSON. A few examples against a local deployment:

# List configured venues
curl -X GET "http://localhost:9050/api/venues"

# List instruments
curl -X GET "http://localhost:9050/api/listings"

# Check simulator status
curl -X GET "http://localhost:9050/api/venuestatus"

# Create a new venue
curl -X POST -d '{"id": "NewExchange", "name": "NewExchange", "engineType": "Matching",
  "restPort": 9087, "orderOnStartup": true, "randomPartyCount": 1}' \
  http://localhost:9050/api/venues

The HTTP layer is configured in market_simulator.xml. One behaviour worth knowing: if a request carries the optional X-API-Version header and it does not match the simulator’s major version, the engine responds with 412 Precondition Failed — omit the header to skip the check. The complete endpoint reference is published in the official REST API documentation.

Liquibase Database Migrations

QuantReplay stores venues, listings, market phases, price seeds, data sources and settings in a shared PostgreSQL database (simdb), and manages that schema with Liquibase. The changelogs live in the db/ directory of the repository — one YAML changelog per table (venue, listing, market_phase, price_seed, data_source, setting, column_mapping), plus constraints, keys, sequences and sample data, all rooted in root-changelog.yml.

In the Docker quickstart you never run Liquibase by hand: the ghcr.io/quod-financial/liquibase container starts once the database is healthy, applies every pending changeset, seeds the demonstration data, and exits — and only then does the engine container boot (condition: service_completed_successfully). Because every schema change ships as a new changeset, upgrading QuantReplay is simply a matter of pulling newer images and re-running docker compose up -d; Liquibase applies exactly the migrations your database is missing and nothing else. The same changelogs can be applied with a standalone Liquibase CLI if you manage your own PostgreSQL instance.

Supported Asset Classes and Use Cases

QuantReplay simulates any order-driven venue, which covers equities, foreign exchange, futures and other listed derivatives, exchange-listed fixed income, and digital assets. Quote-driven workflows (streaming quotes, RFQ) are on the public roadmap.

Three use cases dominate in practice:

  • Strategy backtesting. Feed historical or synthetic data into the simulator and execute a strategy against a live order book that accounts for queue position, partial fills and slippage — far closer to production reality than vectorised backtests.
  • Market microstructure and latency testing. Recreate a high-frequency environment with configurable order book depth and activity rates to measure order acknowledgment latency and system responsiveness under load.
  • Training AI/ML execution models. Use the simulator as a reinforcement learning environment where an agent places orders across venues and is rewarded on execution quality — price improvement, slippage, fill ratio.

These are the same problems Quod Financial’s production systems solve every day. Our teams use QuantReplay to exercise Smart Order Routing (SOR) decisions, validate Execution Management System (EMS) workflows, stress-test OMS order lifecycles and tune algorithmic trading logic before any release reaches a client environment. Releasing the simulator as open source gives every trading team access to that same institutional-grade testing loop.

Frequently Asked Questions

What is the QuantReplay engine?

QuantReplay is an open-source, self-hosted market simulation engine developed by Quod Financial. It creates order-driven trading venues with a full price/time priority matching engine, a QuickFIX-based FIX acceptor, market data publishing, random order generation and historical data playback. Each venue runs as a single native C++ process backed by a shared PostgreSQL database. It supports equities, FX, futures and derivatives, exchange-listed fixed income and digital assets. Originally used internally by Quod Financial to validate execution strategies, it was released publicly in July 2025 under the Apache 2.0 license and is deployed via Docker.

Where can I find the QuantReplay GitHub repository?

The QuantReplay source code is hosted at github.com/Quod-Financial/quantreplay, maintained by Quod Financial under the Apache 2.0 license. The repository includes the C++ engine source, the configuration templates (market_simulator.xml, configSim.txt and FIX dictionaries), the Liquibase database changelogs and the documentation source. Prebuilt Docker images are published to the GitHub Container Registry, and full documentation is available on the project’s GitHub Pages site and wiki.

What is configSim.txt in QuantReplay and what does it configure?

configSim.txt is the QuickFIX configuration file of the QuantReplay engine. It defines the FIX acceptor session: ConnectionType=acceptor, the SocketAcceptPort (9051 in the official template), the FIXT.1.1 session layer with FIX 5.0 SP2 application dictionaries, the SenderCompID and TargetCompID identifiers, heartbeat interval, and message persistence settings. The file sits in the cfg/ directory of a deployment — generated automatically on the first Docker Compose run — and is referenced by the engine’s main configuration file, market_simulator.xml, through its <config> element.

How does QuantReplay use QuickFIX?

QuantReplay embeds the QuickFIX library as its FIX engine and always runs as an acceptor: it listens on port 9051 for inbound connections from client applications acting as initiators. Session parameters — BeginString FIXT.1.1, DefaultApplVerID 9 (FIX 5.0 SP2), CompID pairs such as SIM_XETRA / CLIENT_XETRA, and heartbeat interval — are all defined in configSim.txt, and several [SESSION] blocks can share one port, for example separate order and market data sessions. QuickFIX session logs are visible with docker logs on the venue container (for example, docker logs XETRA).

What ports does the QuantReplay engine use for its FIX and REST APIs?

The QuantReplay engine exposes two ports: port 9051 for the FIX API (the QuickFIX acceptor your trading clients connect to) and port 9050 for the REST API used for administration. Running locally via the official Docker Compose file, these are reachable at localhost:9051 (FIX) and localhost:9050 (REST); the quickstart additionally maps PostgreSQL to host port 15432. Both engine ports are declared in docker-compose.yml, and the FIX port must match the SocketAcceptPort value in configSim.txt.


QuantReplay is an open-source initiative by Quod Financial, a provider of multi-asset trading technology. Explore the project on GitHub, read the documentation, or visit quantreplay.com. Questions or contributions are welcome via GitHub Issues and Discussions, or at info@quodfinancial.com.