Python backtesting library for systematic strategies
Rust core, Python API. Realistic execution modeling, sub-second performance, reproducible research workflows.
5,274 downloads on PyPI in the last 30 days
import manifoldbt as bt
from manifoldbt.indicators import close, sma, rsi
fast = sma(close, 20)
slow = sma(close, 50)
signal = bt.when((fast > slow) & (rsi(close, 14) < 70), 1.0, 0.0)
strategy = (
bt.Strategy.create("momentum")
.signal("signal", signal)
.size(signal * 0.25)
.stop_loss(pct=3.0)
.take_profit(pct=8.0)
)
result = bt.run(strategy, config, store)
print(result.summary())Built-in visualizations
Publication-ready charts out of the box. Tearsheets, parameter sweeps, risk analytics, all with a single function call. Click a figure to see it in full.
Five of the built-in figures. Sweep maps, walk-forward folds, Monte Carlo fans and permutation tests are one call each as well, drawn on a real strategy in the research workflow →
Execution modeling
The gap between backtest and live performance is driven by execution assumptions. Each component is modeled independently and configurable per venue.
| Dimension | Typical framework | manifoldbt |
|---|---|---|
| Fee model | Flat percentage or fixed cost | Maker/taker split, minimum fee, per-venue configuration |
| Slippage | Fixed bps or ignored entirely | Fixed-bps, spread-based, or size-aware volume-impact model, opt-in |
| Funding rates | Not modeled | Per-bar funding accrual from the venue's historical funding-rate series |
| Borrow costs | Not modeled | Short borrow charged per bar from an annual rate, per venue |
| Order types | Market orders only | Market, limit, stop, stop-limit, market-if-touched, stop-loss, take-profit, trailing stop |
| Reproducibility | Depends on random seeds and data snapshots | Deterministic bit-for-bit replay via cryptographic manifests |
What the engine covers
Data connectors
Built-in providers fetch and normalize market data into Arrow IPC. Parallel ingestion with progress tracking, import from any source.
Crypto exchanges
Spot & perpetuals
Spot & perpetuals
Perpetuals L1
Perpetuals v4 (decentralized)
Spot, BTC, ETH, EUR & USD pairs
BTC & ETH options, futures and perpetuals
Stocks, futures, FX and indices
Massive and Databento go down to tick. Yahoo and IEX are landing next, free and daily.
Stocks, ETFs, futures, FX, indices. Daily bars, back to 1970.
US equities and ETFs, IEX exchange tape
Stocks, ETFs, futures, options, forex, and crypto spot
CME, NASDAQ, OPRA, tick to daily
All data is stored locally as Arrow IPC (per-symbol, multi-resolution), instant replay, no re-download.
Speed, measured in public
The engine is written in Rust and operates on Apache Arrow columnar arrays. Data flows through the pipeline with zero-copy semantics and SIMD-friendly memory layout.
These figures are ours. The engine is also measured in public CI against vectorbt and RaptorBT, all three installed from PyPI on a free GitHub runner, with the raw results published and the workflow open to anyone who wants to re-run it. See the reproducible benchmark →

Write it with your agent
A model working from memory invents signatures that read well and never compile. Give it the reference through MCP and the first draft runs; the fix loop, and the quiet bugs it leaves behind, never start.
Claude on its own
no referenceFive turns, four of them reading an error back. What finally runs carries whatever the compiler cannot see.
- youadd a regime filter to my ETH strategy using BTC's trend
- claudewriting strategy.py
- engineerror: 'close' is not callable
- claudefixing
- engineerror: chained comparisons (a < b < c) are not supported
- claudefixing
- engineerror: SymbolRef requires orchestrator-level handling
- claudefixing
- engineerror: empty bar dataset
- claudefixing
- engineok, 1,412 trades
- #runs. BTC is read one bar early; nothing raised.
manifoldbt + MCP
mcp.manifoldbt.comOne lookup, one draft. The rules the compiler enforces arrive before the code is written, not after.
- youadd a regime filter to my ETH strategy using BTC's trend
- claudesearch_docs("reference another symbol")
- mcpCross-Asset References, symbol_ref(), a worked example. 64 ms.
- claudewriting strategy.py
- engineok, 1,388 trades
- #runs, first try. warmup_bars set, symbol_ref() inside the signal.
Research tools
ProBuilt-in tools to validate strategies before deploying capital. Every analysis runs in Rust, no Python bottlenecks.
Walk-forward optimization
Split your data into train/test folds. Optimize parameters in-sample, validate out-of-sample. Compare stitched OOS equity against the full backtest to detect overfitting.


Monte Carlo analysis
Bootstrap returns to estimate tail risk and P(ruin), or permute return order to measure path dependency and drawdown distribution.

Safety checks
ProAutomated diagnostics that catch common backtesting pitfalls. Run them before trusting any result.
Lookahead bias detection
Tests every signal for future data leakage and names the one that leaks. Catches the bugs that silently inflate a backtest.
$ bt.diagnostics.detect_lookahead(strategy, config, store)Lookahead Bias Detection Report================================Tolerance: 1.0%Signal 'fast' no future data okSignal 'slow' no future data okSignal 'rsi' no future data okSignal 'entry' no future data okPosition sizing no future data okResult: CLEAN - no lookahead bias detected
Exposure stability
Verifies that strategy exposure is consistent when you extend or truncate the backtest period. Detects regime-dependent behavior.
$ bt.diagnostics.check_exposure_stability(strategy, config, store)Exposure Stability Report=========================Exposure drift, window 1: 0.3% okExposure drift, window 2: 0.8% okRegime sensitivity: stable across 3 windowsResult: STABLE - exposure consistent across time ranges
Pricing
The full engine is free. Pro lifts the research caps: unlimited sweeps, one-second bars, walk-forward, Monte Carlo without a limit, GPU.
- Rust-powered engine
- All 104 indicators
- Multi-asset
- CSV / DataFrame import
- Engine resolution: 1m
- Timeseries output: Daily
- Monte Carlo resampling: 1,000 sims
- Parameter sweeps (all-core, 2-D, batch): 256 combos
- Crypto connectors (Binance, Bybit, Hyperliquid, dYdX, Bitstamp)
- MCP server (AI agent integration)
- Tearsheets & export
- Seats: 1
- Rust-powered engine
- All 104 indicators
- Multi-asset
- CSV / DataFrame import
- Engine resolution: 1s
- Timeseries output: Up to 1s
- Monte Carlo resampling: Unlimited
- Parameter sweeps (all-core, 2-D, batch): Unlimited
- Crypto connectors (Binance, Bybit, Hyperliquid, dYdX, Bitstamp)
- MCP server (AI agent integration)
- Tearsheets & export
- Safety checks (lookahead, exposure)
- Cross-exchange backtesting
- Databento & Massive connectors
- Built-in WFO
- GPU acceleration
- Seats: 1
- Rust-powered engine
- All 104 indicators
- Multi-asset
- CSV / DataFrame import
- Engine resolution: 1s
- Timeseries output: Up to 1s
- Monte Carlo resampling: Unlimited
- Parameter sweeps (all-core, 2-D, batch): Unlimited
- Crypto connectors (Binance, Bybit, Hyperliquid, dYdX, Bitstamp)
- MCP server (AI agent integration)
- Tearsheets & export
- Safety checks (lookahead, exposure)
- Cross-exchange backtesting
- Databento & Massive connectors
- Built-in WFO
- GPU acceleration
- Seats: 5
- Managed compute (cloud sweeps, Monte Carlo, WFO)
- Included compute credits: 5,000/mo
- Hosted data credits (Databento, Massive): 5,000/mo
- Usage dashboard, spend caps & alerts
- Pay-as-you-go overage
- Priority support: Direct channel
In detail: what Pro unlocks, what Team includes, what Firm adds
FAQ
Learn backtesting in Python
Step-by-step guides, runnable strategy walkthroughs, and honest comparisons, all built on realistic, reproducible backtests.
Guides
- How to Backtest a Trading Strategy
A step-by-step Python walkthrough: from raw bars to a realistic backtest and a tearsheet.
- What Is Backtesting?
What backtesting is, why it works, where it lies to you, and how to do it honestly in Python.
- Algorithmic Trading in Python
The libraries, the workflow, and a runnable parameter sweep to research systematic strategies.
- Walk-Forward Optimization in Python
Optimize in-sample, validate out-of-sample, fold by fold, the honest way to tune parameters.
- Realistic Backtest Execution
Slippage, market impact, funding, partial fills, and signal delay: why most backtests lie, and how to fix it.
Compared to other libraries
- Manifold-BT vs RaptorBT
Two Rust engines, benchmarked head to head: both fast on one call, but Manifold-BT is 25x faster on the parameter sweeps that validate a strategy.
- Manifold-BT vs Freqtrade
An honest comparison: fast, realistic backtesting versus live crypto trading, and when to use each.
- Manifold-BT vs vectorbt
Rust engine with vectorized signals and a sequential fills pass, versus vectorized NumPy: speed, realism, path-dependent logic.
- Manifold-BT vs Backtrader
A fast, realistic research engine versus a mature pure-Python framework, and when each fits.
- Manifold-BT vs NautilusTrader
A research backtesting library with fast parameter sweeps and GPU, versus a full event-driven platform built for live trading and backtest-to-live parity.
Or browse 15 Python trading strategies, each with runnable code and a backtest, see all strategies →
Run it on your own strategy
The full engine is free, on your machine, with your data. The speed figures on this page come from a public CI run, if you would rather check them first.