FastMM
Documentation: https://ziy.bio/FastMM/
FastMM is a fast market-making engine in C++20.
- Backtests, replay and live trading run the same strategy code.
- Strategies are written in C++ or Python. Python quoting hooks are compiled with Numba and called on the trading thread; model code runs as ordinary Python on another thread.
- Every session is recorded, and replaying a recording sends the same orders again.
- Orders pass pre-trade risk limits before they are sent, and reaching the loss limit cancels all orders.
- The trading thread does not allocate memory or wait on network I/O; in simulation a market-data update becomes an order in about 120 nanoseconds (p50 on one core of a desktop; bench/README.md says what that measurement contains and what it leaves out).
Quick start
pip install "fastmm-engine[hot]" # Linux x86-64, CPython 3.9+
fastmm init my-mm && cd my-mm && python backtest.py # a strategy, a config and a backtest
The C++ programs ship as a release tarball and as ghcr.io/ziyangliu-666/fastmm (Deploy a release). Building them needs Linux, gcc 13+ or clang 16+, CMake 3.25+, Ninja, OpenSSL 3 and zlib:
git clone https://github.com/ziyangliu-666/FastMM && cd FastMM
./scripts/bootstrap.sh # checks toolchain, configures the release preset
cmake --build --preset release -j && ctest --preset release -j"$(nproc)"
./build/release/bin/fastmm-backtest --config configs/backtest-example.toml --data synthetic --out runs/first
python3 tools/report.py runs/first # -> runs/first/report.html, open it
./scripts/run-sim.sh --duration 30s # sim exchange + live engine, ends with a report
On real data, a day of Binance BTCUSDT perpetual at the venue's own fees:
python3 python/fastmm/data/__main__.py fetch --symbol BTCUSDT --date 2024-03-27
./build/release/bin/fastmm-backtest --config configs/backtest-binance.toml \
--data binance:BTCUSDT,2024-03-27
What that result means, and what it cannot: Backtest on real BTCUSDT data.
Write a strategy
#include "fastmm/strategy.hpp"
using namespace fastmm;
struct MyParams {
FASTMM_PARAMS(MyParams)
FASTMM_PARAM_BPS(half_spread_bps, 0.005_bps, 0_bps, 1000_bps, "half spread around the mid, bps")
FASTMM_PARAM(Qty, quote_qty, 0.001_qty, 0_qty, 1000_qty, "quantity per side, base units")
};
struct MyMM : StrategyBase<MyParams> {
static constexpr std::string_view name() noexcept { return "my_mm"; }
void on_book(auto& ctx, InstrumentId id, const auto& book) noexcept {
if (!book.is_valid()) return ctx.pull_quotes(id); // empty or crossed
const Instrument& inst = ctx.instrument(id);
const Price half = book.mid() * params().half_spread_bps;
DesiredQuotes q;
q.bid(inst.round_price(book.mid() - half, Side::Buy), inst.round_qty(params().quote_qty));
q.ask(inst.round_price(book.mid() + half, Side::Sell), inst.round_qty(params().quote_qty));
ctx.set_quotes(id, q); // diffed against resting orders
}
};
Next: tutorial, or a strategy in Python.
Limitations
- Exchanges: Binance Spot, Binance USDⓈ-M perpetuals, Bybit spot, Deribit, and Nasdaq ITCH market data.
- Linux on x86-64 only.
- The shipped strategies are reference implementations, not an edge: the example backtest is profitable only because it is configured with a maker rebate (Economics).
- No state survives a restart, monitoring is a status file to pull from (
fastmm-top, or its Prometheus endpoint) with no alerting of its own, and venue-side cancel-on-disconnect is armed only on Deribit (Running this in production).
Metadata
Release files for fastmm-engine 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fastmm_engine-0.2.0.tar.gz | 4.0 MB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| fastmm_engine-0.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.14 | CPython 3.14 | Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 | Details |
| fastmm_engine-0.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.13 | CPython 3.13 | Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 | Details |
| fastmm_engine-0.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.12 | CPython 3.12 | Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 | Details |
| fastmm_engine-0.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.11 | CPython 3.11 | Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 | Details |
| fastmm_engine-0.2.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.10 | CPython 3.10 | Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 | Details |
| fastmm_engine-0.2.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.9 | CPython 3.9 | Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 | Details |
Total release size: 13.0 MB
Release files / fastmm_engine-0.2.0.tar.gz
| Download URL | fastmm_engine-0.2.0.tar.gz |
|---|---|
| Size | 4.0 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
28ad7db1fe0f6da3ea350f68f74448d48fa705b1a0e90662a7f21bc539e2ba7c
|
|
BLAKE2b-256 checksum How to use checksums |
6a98453feeab44f10ce82f3e2932a7ad85700ad639b6035d39c19dc730464584
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / fastmm_engine-0.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | fastmm_engine-0.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.14 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
1fc7fc6c1b3cb80ebfaeda3db747f15e36faf3bc7a8ff004de6e47f0901d4dd0
|
|
BLAKE2b-256 checksum How to use checksums |
883cf73088a8c14e2723075f7629e73cadf1068de83797a7e4ad5c478c6e6858
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / fastmm_engine-0.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | fastmm_engine-0.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.13 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
1a91413f3925f3f83f7f76f6073991ec8c81302d4b6e8a0f8f0aa817d3517517
|
|
BLAKE2b-256 checksum How to use checksums |
594925fd2406cf307e37911a2a7497a3571b2626df8409add8374ca588fbf85d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / fastmm_engine-0.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | fastmm_engine-0.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
0a93e31754dc69948d7edcb3910001f4c3d34bff21d4f786978003313238e69f
|
|
BLAKE2b-256 checksum How to use checksums |
38b086f2b5d1e208dec00fe5fade59b171085839e99f6934ea14dc087b6485df
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / fastmm_engine-0.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | fastmm_engine-0.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
0c703b6a23ca68070a132c955fe9fd0b8d08c44f4938da160da9522e79146547
|
|
BLAKE2b-256 checksum How to use checksums |
1e1e31eed53d6c61a273584d39bccbfda405a696280d72735613955efdfd043a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / fastmm_engine-0.2.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | fastmm_engine-0.2.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.10 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
f270a08ed4217805c7d39efdbbc6a369a410b21e2f622885dc108032659d9c75
|
|
BLAKE2b-256 checksum How to use checksums |
c34ad1d87ece1e1017149bab26306791c95619013091c0c9a2e8e845ab85ded2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / fastmm_engine-0.2.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | fastmm_engine-0.2.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.9 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
585046db820504f7973508bcd64d74c498fa31ab7ca78735f38f043a343baf63
|
|
BLAKE2b-256 checksum How to use checksums |
94b3a9f00996830b22993735980842ae189c814448e62ce7bf78c3ee6a1fd056
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|