Skip to content

Getting Started

Learning objectives

After reading this page you will understand:

  • What EduMatcher is, and why it is split into many pm-* processes
  • The smallest useful path from installation to a first trade
  • The handful of concepts that make the rest of the guide easier to read
  • How configuration, data files, market data, logs and reports fit together
  • Which chapters to read next for your role

What EduMatcher is

EduMatcher is a working educational exchange. It has a real matching engine, real order books, session phases, auctions, market-maker quoting, risk controls, statistics, clearing-style P&L, audit logs, external gateways, market-data feeds, post-trade feeds, monitoring tools and autonomous bot traders.

That makes it useful for three different kinds of learning:

  • Market microstructure — what happens inside an order book, why auctions exist, how spreads, time priority, market makers and risk controls change the market
  • Exchange operations — how to configure a venue, start the processes, run a session, monitor it, stop it and inspect what happened afterwards
  • Protocol and system design — how order entry, market data, post-trade dissemination, drop copy, logging and recovery semantics are separated in a multi-process system

The project is intentionally bigger than a toy. The User Guide is long because the system covers the whole exchange surface, not because you must learn every chapter before typing your first order. This page is the map.

If you are new to exchanges

Read How an Exchange Works before the rest of the User Guide. It explains the domain without assuming you already know what a book, fill, auction, market maker or drop-copy feed is.

The system in one picture

EduMatcher is a set of independent processes connected by message streams. The engine is the only process that owns the order books. Everything else either sends commands to the engine, listens to events from it, or exposes those events to another audience.

flowchart LR
    subgraph order_entry["Order entry and control"]
        ALF["pm-alf-console\ninteractive traders"]
        ALFGWY["pm-alf-gwy\nexternal ALF clients"]
        BALF["pm-balf-gwy\nbinary clients"]
        ADM["pm-admin / pm-admin-cli\noperator commands"]
        BOTS["pm-ai-trader / pm-ai-swarm / pm-mm-bot\nautomation"]
    end

    ENG["pm-engine\nmatching engine\norder books"]

    subgraph observers["Internal observers"]
        CLR["pm-clearing\nP&L"]
        STATS["pm-stats\nOHLCV / VWAP / mid"]
        AUDIT["pm-audit\naudit log"]
        IDX["pm-index\nmarket index"]
    end

    subgraph external["External and visual interfaces"]
        CALF["pm-md-gwy\nCALF market data"]
        API["pm-api-gwy\nREST / WebSocket"]
        RALF["pm-ralf-gwy\npost-trade feed"]
        DC["pm-dc-gwy\ndrop-copy TCP"]
        TERM["TapeDeck / pm-terminal\ntrader information terminal"]
        LOG["pm-log-srv / pm-log-ui\ncentral logs"]
    end

    ALF --> ENG
    ALFGWY --> ENG
    BALF --> ENG
    ADM --> ENG
    BOTS --> ENG
    ENG --> CLR
    ENG --> STATS
    ENG --> AUDIT
    ENG --> IDX
    ENG --> CALF
    ENG --> API
    ENG --> RALF
    ENG --> DC
    CALF --> TERM
    API --> TERM
    LOG -. receives logs from .- ENG
    LOG -. receives logs from .- external

The important first idea is this: the exchange is not one command. It is a small operating environment. For a five-minute demo you only need pm-engine and two pm-alf-console terminals. For a classroom or realistic session you add configuration, the scheduler, clearing, statistics, market data, logging and visual displays.

The five concepts to learn first

You do not need every detail yet. These concepts are enough to make the rest of the guide readable.

Concept What it means Read more
Engine pm-engine, the authoritative process that owns all order books and matches orders Running the Exchange, Processes
Symbol A tradeable instrument such as AAPL, with tick size, reference prices, optional market-maker seeds and risk settings Configuration, Risk Controls
Gateway ID The identity a trader, bot or operator uses when connecting; roles such as TRADER, MARKET_MAKER and ADMIN are attached to gateway IDs Configuration, Gateway Concepts
Session phase Where the trading day is: PRE_OPEN, OPENING_AUCTION, CONTINUOUS, CLOSING_AUCTION, CLOSED, or a halt-related phase Auctions & Scheduling
Deployed configuration The running system reads one compiled artifact at <EDUMATCHER_DATA_DIR>/ref_data/engine_config.json; you edit YAML, then deploy it Configuration

Two more ideas become important once you start observing or integrating:

  • Events and records are not the same thing. The engine publishes live events. pm-stats, pm-clearing, pm-audit, pm-index and the log server turn those events into durable records. See Persistence.
  • Internal tools and external protocols are separate. Local processes use ZeroMQ around the engine. External clients use ALF, BALF, CALF, RALF, DC1 or the API gateway. See External Protocols Overview.

How to approach the documentation

The User Guide is arranged roughly in layers:

Layer Chapters Use them when...
Start and configure Getting Started, Configuration, Config Verifier, Config GUI, Running the Exchange You need to install, create a session config, deploy it and start processes
Trade Gateway Reference, Order Types, Combo Orders, Auctions & Scheduling, Market Making You want to understand what traders and market makers can do
Operate Risk Controls, P&L & Clearing, Statistics, Market Index, Exchange Commands, Processes You are running a classroom, demo or test venue and need control and observability
Persist and audit Persistence, Audit Trail, Drop Copy, Centralized Log Server You need to know what gets written, where, and how to inspect or replay it
Integrate External Protocols Overview, ALF, BALF, CALF, RALF, API Gateway, protocol appendices You are writing a client, feed handler, dashboard or post-trade consumer
Observe visually TapeDeck, Log Operator Console, ticker/board/viewer process sections You want browser or terminal displays for a running market
Practice Examples, Example Engine Configs, Training You want guided exercises rather than reference material

The Training Guide is the most beginner-friendly hands-on route. The User Guide is the reference; the training chapters are the guided lab.

Installation

Choose one installation mode. The commands later in this chapter are shown in installed mode. In developer mode, prefix pm-* commands with poetry run.

Mode Best for What you install Command style
VM bootstrap Workshops, clean demos, avoiding host setup Multipass VM with EduMatcher installed inside it multipass shell edumatcher-vm, then pm-engine
pipx Students and instructors running a local session EduMatcher commands on your host PATH pm-engine
Poetry checkout Development, tests, changing source code Repository plus dev dependencies poetry run pm-engine

VM bootstrap - ready-to-run Multipass VM

Use this when you want the fewest host-machine assumptions. Your host needs Multipass and curl; Python, Poetry and EduMatcher are installed inside the VM.

curl -fsSL https://raw.githubusercontent.com/johan162/EduMatcher/main/vm/curl_setup_vm.sh | \
    bash -s -- --version 0.20.3 --snapshot

multipass shell edumatcher-vm
cd /home/ubuntu/session
pm-engine --verbose

Useful options:

# Name the VM and take an initial snapshot
curl -fsSL https://raw.githubusercontent.com/johan162/EduMatcher/main/vm/curl_setup_vm.sh | \
    bash -s -- --name edumatcher-vm --version 0.20.3 --snapshot

# Tune resources
curl -fsSL https://raw.githubusercontent.com/johan162/EduMatcher/main/vm/curl_setup_vm.sh | \
    bash -s -- --cpus 2 --memory 3G --disk 8G

If you prefer to inspect the script first:

curl -fsSL https://raw.githubusercontent.com/johan162/EduMatcher/main/vm/curl_setup_vm.sh -o curl_setup_vm.sh
less curl_setup_vm.sh
bash curl_setup_vm.sh --version 0.20.3 --snapshot

End-user / student mode - pipx

Use this when you want to run EduMatcher directly on your host, without a source checkout or Poetry environment.

Requirements:

Requirement Notes
Python 3.13 or later Check with python --version
pipx Installs command-line applications into isolated environments
Several terminals Or tmux / screen; one process per pane is normal

Install pipx if needed:

# macOS with Homebrew
brew install pipx
pipx ensurepath

# Linux / generic Python install
python -m pip install --user pipx
python -m pipx ensurepath

Install EduMatcher and bootstrap a session directory:

pipx install edumatcher
mkdir edumatcher-session
cd edumatcher-session
pm-setup

pm-setup prepares the data directory, deploys the bundled sample configuration, and prints the EDUMATCHER_DATA_DIR line to add to your shell profile. Open a new terminal after updating your profile so every pm-* command sees the same data directory.

Developer mode - Poetry checkout

Use this when you are changing code, running tests, or working with the docs from source.

git clone https://github.com/johan162/EduMatcher.git
cd EduMatcher
poetry config virtualenvs.in-project true
poetry install --with dev,docs

poetry run pm-engine --verbose
poetry run pm-alf-console --id TRADER01

Developer mode uses the repository-local defaults. When exact behavior matters, use the same deployed-configuration flow as installed mode: author YAML, run poetry run pm-config-deploy ..., then restart the processes.

Environment variables

EduMatcher has one runtime location variable:

Variable Default in installed mode Default in source checkout Purpose
EDUMATCHER_DATA_DIR ~/.local/share/edumatcher <repo>/src/data/ Root directory for deployed reference data and runtime data files

Every process reads the deployed config from <EDUMATCHER_DATA_DIR>/ref_data/engine_config.json. Set this variable once in your shell profile or launcher so every process in a session sees the same configuration and writes to the same data area.

How the default is selected

The data directory is selected when the EduMatcher Python package is imported; it is not selected from the process's current working directory:

  1. If EDUMATCHER_DATA_DIR is set, its expanded and absolute path wins in both development and installed deployments.
  2. Otherwise, EduMatcher checks where edumatcher/config.py is installed. If its package parent is named src, EduMatcher treats the process as running from a source checkout and uses <repo>/src/data/.
  3. Otherwise, EduMatcher treats the package as installed and uses ~/.local/share/edumatcher (for example, /Users/<user>/.local/share/edumatcher on macOS).

This means running an installed command from inside a repository does not make it a source checkout, and running a Poetry command from another directory does not change the source-checkout data location. All processes in one exchange must use the same EDUMATCHER_DATA_DIR value when an explicit shared location is needed.

The authored YAML may live elsewhere, but deployment always installs the compiled artifact and its copied source under the selected data directory:

<DATA_DIR>/ref_data/engine_config.json
<DATA_DIR>/ref_data/engine_config.yaml

Configured relative runtime paths such as data/stats.db are also resolved under <DATA_DIR>, so they refer to the same files regardless of the command's working directory. Absolute paths remain explicit overrides.

Configuration: edit YAML, deploy artifact

EduMatcher separates the file you edit from the file the exchange runs.

File Purpose
engine_config.yaml Authored configuration. Keep this in your session directory or version control. Edit this.
<EDUMATCHER_DATA_DIR>/ref_data/engine_config.json Compiled deployed artifact. Every running process reads this. Do not edit it by hand.

Why this matters: a multi-process exchange is dangerous if each process can be pointed at a different file. EduMatcher avoids that. You deploy once, then every process reads the same artifact.

Typical loop:

# Start from the sample copied by pm-setup, or generate a new authored file
pm-config-gen \
    --symbols AAPL MSFT TSLA \
    --gateways TRADER01:TRADER TRADER02:TRADER OPS01:ADMIN MM01:MARKET_MAKER \
    --output engine_config.yaml

# Validate only
pm-config-deploy --check engine_config.yaml

# Validate, compile and install as the deployed artifact
pm-config-deploy engine_config.yaml

# Confirm where the deployed config lives
pm-config-deploy --show

For the full field reference, see Configuration. For a visual editor, see Configuration GUI. For a catalog of ready-made examples, see Example Engine Configs.

Your first session: one trade in five minutes

This path uses the sample configuration installed by pm-setup. It has TRADER01, TRADER02, OPS01, MM01 and symbols such as AAPL, MSFT and TSLA. Session scheduling is disabled in the sample, so matching is available immediately.

Open three terminals in the same session environment.

Terminal 1 - start the engine

pm-engine --verbose

Wait until the engine has bound its sockets and printed the deployed configuration it is using. Leave this process running.

Terminal 2 - connect the seller

pm-alf-console --id TRADER02

At the TRADER02> prompt, post a resting sell order:

NEW|SYM=AAPL|SIDE=SELL|TYPE=LIMIT|QTY=100|PRICE=150.00|TIF=DAY

Terminal 3 - connect the buyer

pm-alf-console --id TRADER01

At the TRADER01> prompt, buy at the same price:

NEW|SYM=AAPL|SIDE=BUY|TYPE=LIMIT|QTY=100|PRICE=150.00|TIF=DAY

Both gateways should report a fill. The engine matched the buy and sell because the bid price was high enough to trade with the resting ask.

sequenceDiagram
    participant S as TRADER02
    participant E as pm-engine
    participant B as TRADER01

    S->>E: NEW SELL AAPL 100@150.00
    E-->>S: ACK -> RESTING
    B->>E: NEW BUY AAPL 100@150.00
    E-->>B: FILL BUY 100@150.00
    E-->>S: FILL SELL 100@150.00
    E-->>E: publish trade.executed

That is the core of the system. Everything else in EduMatcher either changes what orders can do, changes when matching is allowed, observes what happened, or exposes the same activity to other clients.

What if the order fills before the other trader acts?

Your configuration may contain market-maker seed quotes. In that case an aggressive order can trade against the seeded quote instead of waiting for the other participant. That is not a bug; it means the book already had liquidity. Read Market Making when you are ready for that layer.

Add one process at a time

After the first trade, add observers. This is the safest way to learn the system: start with the engine and gateways, then add one new responsibility at a time.

When you want to... Start this Then read
See one live order book pm-viewer --symbol AAPL Order Types, Processes
See a multi-symbol board or ticker pm-board, pm-ticker Statistics and Reporting
Record OHLCV, VWAP and mid prices pm-stats Statistics and Reporting
Track positions and P&L pm-clearing P&L & Clearing
Capture a full audit log pm-audit Audit Trail, Persistence
Drive opening and closing phases by time pm-scheduler Auctions & Scheduling
Run operator commands pm-admin or pm-admin-cli Risk Controls, Exchange Commands
Publish external market data pm-md-gwy Market Data Feed (CALF)
Open the browser trader terminal TapeDeck / pm-terminal stack Trader Information Terminal
Collect logs from all processes pm-log-srv, then pm-log-cli or pm-log-ui Centralized Log Server, Log Operator Console

The full process catalog is in Processes. Use that chapter when you want exact command-line flags and startup dependencies.

What the major feature areas are for

Trading and order behavior

Start here if you are a trader, market maker or instructor building exercises.

Operations and controls

Start here if you are running the venue.

Observation, reports and records

Start here if you need to explain or audit what happened.

External connectivity

Start here if you are writing a client or integration.

Roadmaps by role

You can read the whole guide front to back, but most readers should not start that way. Pick the path that matches what you are trying to do.

Role or goal Suggested path
Beginner learning the market How an Exchange Works -> this page -> Training chapters 00-08 -> ALF Console
Student trader Installation -> first session -> ALF Console -> Order Types -> Auctions & Scheduling
Instructor running a class Installation -> Configuration -> Running the Exchange -> Processes -> Training
Market maker Market Making -> Market-Maker Bot -> ALF Console
Operator / supervisor Running the Exchange -> Risk Controls -> Exchange Commands -> Centralized Log Server
Analyst / auditor P&L & Clearing -> Statistics and Reporting -> Audit Trail -> Persistence
Dashboard or feed developer External Protocols Overview -> CALF or API Gateway -> protocol appendices
Core developer Developer install -> Architecture -> Developer Practice -> tests for the subsystem you are changing

Three details worth knowing early

Prices are exact integer ticks internally

Displayed prices look like money: 150.25. Internally, the engine matches on integer ticks. With tick_decimals: 2, 150.25 is stored as 15025 ticks. This avoids floating-point drift in matching, turnover and reports.

Most commands, CLIs and APIs convert for you. Raw SQLite rows may show the tick form. Read Prices are stored as integer ticks before doing direct SQL analysis.

Instants and trading dates are different

Event timestamps are UTC instants. Daily OHLCV, clearing summaries and index rows are grouped by the exchange's local trading date. If a session crosses midnight UTC, one trading day can span two UTC dates.

If you run pm-stats and pm-clearing with a non-default timezone, give both the same value:

pm-stats --timezone Europe/Stockholm
pm-clearing --timezone Europe/Stockholm

Read The trading date before comparing daily reports.

Empty books are normal until someone provides liquidity

An exchange does not create bids and asks by itself. The book has liquidity only when orders rest in it. For demos, you can provide liquidity manually, by seeded market-maker quotes in configuration, or with pm-mm-bot / AI traders.

If a beginner sees no fill, the most common reason is simple: nobody is resting on the other side at a price that crosses.

Quick glossary

Term Meaning
Order book The sorted resting buy and sell orders for one symbol
Bid / ask Best available buy price / best available sell price
Spread Difference between best ask and best bid
Fill An execution: two orders matched and traded
TIF Time-in-force: how long an order may remain active (DAY, GTC, ATO, ATC, etc.)
Auction A call phase where orders collect first and execute together at an equilibrium price
Market maker A participant expected to quote both bid and ask liquidity
Circuit breaker A risk control that halts a symbol after a configured price move
Drop copy A copy of fills sent to compliance, audit or risk systems
CALF EduMatcher's external market-data protocol
RALF EduMatcher's external post-trade dissemination protocol
LALF EduMatcher's centralized log protocol

For the full vocabulary, see the Glossary.

Where to go next

If you want a guided path, go to Training. If you want to build your own session, go to Configuration and then Running the Exchange. If you want the complete runtime map, go to Processes.

The rest of the guide is large, but it is not a wall. It is a map of a whole exchange. Start with one process, one symbol and one trade; then add the next layer when the previous one makes sense.