Skip to content

User Guide

ToyQuant is a small C++20 market-making simulator. It reads synthetic market ticks, lets a strategy submit quotes, matches orders, and writes the results to CSV files.

Requirements

  • CMake 3.16 or newer
  • A C++20-capable compiler
  • Python 3 for the optional scenario and UDP tools

Build and Test

Run these commands from the repository root:

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

The main programs are out/build/linux-debug/toy_quant for the simulation and out/build/linux-debug/backtest_main for metrics from recorded data.

Run with CSV

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

The command format is:

./out/build/linux-debug/toy_quant csv [tick_file] [delay_ms] [strategy]

delay_ms is normally 0; use a positive value to slow down the tick stream. The available strategies are naive and optimized, with optimized as the default.

Run with UDP

Start the simulator:

./out/build/linux-debug/toy_quant udp 9000 optimized

In another terminal, send a scenario:

python3 tools/udp_sender.py 127.0.0.1 9000 data/scenarios/sample_ticks.csv 0

CSV mode is easier for repeatable experiments; UDP mode is useful for observing a streaming feed.

Scenarios

Scenarios are CSV files containing synthetic market ticks. They make it easy to run the same strategy against different market conditions. Built-in files live in data/scenarios/:

File Market behavior
sample_ticks.csv Small input for a quick run
synthetic_ticks.csv General-purpose mixed sample
flat_ticks.csv Mostly stable prices
uptrend_ticks.csv Rising prices
downtrend_ticks.csv Falling prices
shock_ticks.csv Sudden price movement
random_ticks.csv Noisy price movement

The generated scenarios contain 1,000 ticks each; sample_ticks.csv is intentionally small for quick format checks. Keep the scenario file fixed when comparing naive and optimized, and remember that runtime CSV files are overwritten by the next simulation.

Generate reproducible scenarios with a fixed seed:

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

Using the same seed recreates the same ticks. For a controlled experiment, keep the scenario and seed fixed, change only the strategy or one parameter, and compare the orders and trades. These scenarios are for learning and regression experiments; they do not represent real market data or production trading performance.

Generate a Visual Report

After running a scenario, create a static report with the three main views:

  • Quotes & Executions: reference tick price, buy/sell quote bands, and execution markers.
  • Quote Distance to Reference Mid: quote displacement from the reference price in ticks.
  • Net Inventory Profile: signed inventory and the configured +/-1000 inventory boundary.

The report also includes a right-side summary panel with order count, executions, traded quantity, fill rate, initial capital, current equity, max drawdown, inventory peak, and unexecuted orders.

Set up the optional plotting environment and generate the report with:

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

The report is a visual diagnostic, not a full PnL report. The input files contain one price per tick rather than complete bid/ask snapshots, so Reference Mid uses the tick price as its visible reference. Runtime CSV files are overwritten by the next simulation.

Inspect Results

Each run updates:

data/runtime/orders.csv
data/runtime/trades.csv

The runtime files begin with a # source_ticks=... metadata line. Reuse that same Tick file for backtest_main; the backtest validates the source when the metadata is available.

The terminal shows tick and summary information. Backtest reports are written under logs/:

./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

Troubleshooting

  • Run commands from the repository root so relative paths resolve correctly.
  • Check that the input CSV exists and uses the expected tick format.
  • Use a non-negative integer for the delay and a UDP port between 1 and 65535.
  • If there are no trades, try shock_ticks.csv or random_ticks.csv; a quiet scenario may not cross the strategy's orders.

For implementation details, see Architecture. Data file details are documented in data/README.md in the repository.