Skip to content

Repository files navigation

ToyQuant

A reproducible C++20 market-making simulator — from ticks to trades to PnL.

C++20 CMake Tests License

User Guide · Architecture · Data Formats


ToyQuant replays market data through the complete trading loop — feed, order book, strategy, matching, execution reports, and backtest metrics — so you can observe every decision a market maker makes, tick by tick.

It is a toy project for learning and experimentation, not a production trading system. APIs, scenarios, and strategy behavior may change between versions.

Demo

$ ./out/build/linux-debug/toy_quant csv data/scenarios/sample_ticks.csv 0 optimized

[TICK] EURUSD ts:1625097601900 price:1.1859 size:100 side:S | Top Bid: 1.1855@150 | Top Ask: 1.1851@50
...
[SUMMARY] submitted_orders=24 submitted_quantity=1302 cancel_requests=9
          trade_reports=11 fill_rate=0.318 cancel_rate=0.375
          net_position=-414 inventory_exposure=414 working_orders=6

The same input and parameters produce deterministic runtime CSV output for this simulator.

How It Works

 CSV scenario ──╮
                ├─► Feed ──► Order Book ──► Strategy ──► Matching Engine ──► orders.csv
 UDP stream ────╯            top of book     naive /       price–time         trades.csv
                                             optimized     priority                │
                                                                                  ▼
                                          backtest_main ──► PnL · equity · max drawdown
  • Two feed modes — replay CSV scenarios or stream ticks over UDP.
  • Two market-making strategiesnaive and optimized behind a common interface.
  • Price–time priority matching with self-trade prevention and partial fills.
  • Stateful execution reports — position and working orders update from trade, cancel, and fill events.
  • Deterministic backtests — realized/unrealized PnL and a reusable drawdown calculation.
  • Small toolchain — CMake, a C++20 compiler, and Python 3 for the optional scenario and report tools.

Quick Start

Requirements: CMake 3.16+, a C++20-capable compiler, and Python 3.

cmake --preset linux-debug
cmake --build --preset linux-debug
ctest --preset linux-debug

Run a CSV scenario (flat, trending, shock, and random markets ship in data/scenarios):

./out/build/linux-debug/toy_quant csv data/scenarios/flat_ticks.csv 0 optimized

Stream ticks over UDP (and send a scenario from another terminal):

./out/build/linux-debug/toy_quant udp 9000 naive
python3 tools/udp_sender.py --port 9000

Replay a backtest from generated order and trade records:

./out/build/linux-debug/backtest_main \
  data/scenarios/sample_ticks.csv \
  data/runtime/orders.csv \
  data/runtime/trades.csv \
  0 0 backtest logs/backtest.log

Generate your own scenarios with a fixed seed for reproducible runs:

python3 tools/gen_ticks.py all --count 1000 --seed 42 --output-dir data/scenarios

Output

Each toy_quant run creates or truncates:

  • data/runtime/orders.csv — every order the strategy submitted.
  • data/runtime/trades.csv — every execution report the engine returned.

Both runtime files include a # source_ticks=... metadata line. Pass the same Tick file to backtest_main; when metadata is present, the backtest rejects a mismatched file. Older runtime files without metadata remain readable.

The default backtest log is logs/backtest.log.

Visual Report

Generate a static report with the market price, strategy quotes, executions, net inventory, and run summary:

python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python tools/plot_report.py \
  --ticks data/scenarios/synthetic_ticks.csv \
  --orders data/runtime/orders.csv \
  --trades data/runtime/trades.csv \
  --output reports/synthetic_ticks_optimized.png

The generated PNG is designed for quick inspection and README screenshots. Runtime CSV files are overwritten by the next simulation, so generate or copy the report before starting another run.

ToyQuant simulation report

Non-Goals

ToyQuant deliberately excludes real exchange connectivity, FIX, a risk gateway, persistence and recovery, nanosecond-latency claims, and full L2 market reconstruction. Keeping these out of scope is what keeps the core loop small enough to read in one sitting.

Documentation

Document Contents
User Guide CLI reference, scenarios, experiments, data contracts, and troubleshooting
Architecture Data flow, module responsibilities, matching rules, order lifecycle
Data Files Tick CSV format, runtime outputs, typical workflow

Contributing

Bug reports, documentation improvements, and focused tests are welcome. Please open an issue before proposing new features.

Disclaimer

This project is for educational purposes only. It does not provide investment advice and must not be used for live trading.


Created and maintained by 12mango · Contact · MIT License

About

An educational C++20 market-making simulator that replays CSV or UDP market data through a simplified order book, strategy logic, matching engine, and backtest analysis. Built with CMake and CTest to help study order flow, inventory behavior, execution reports, and strategy performance in a reproducible environment.

Topics

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages