Python backtesting library for systematic strategies

Rust core, Python API. Realistic execution modeling, sub-second performance, reproducible research workflows.

$pip install manifoldbt
See the benchmark →

5,274 downloads on PyPI in the last 30 days

strategy.py
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())
Same strategy, same data, real-time race
manifoldbt░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
raptorbt░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
vectorbt░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

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.

Fee model
Typical framework
Flat percentage or fixed cost
manifoldbt
Maker/taker split, minimum fee, per-venue configuration
Slippage
Typical framework
Fixed bps or ignored entirely
manifoldbt
Fixed-bps, spread-based, or size-aware volume-impact model, opt-in
Funding rates
Typical framework
Not modeled
manifoldbt
Per-bar funding accrual from the venue's historical funding-rate series
Borrow costs
Typical framework
Not modeled
manifoldbt
Short borrow charged per bar from an annual rate, per venue
Order types
Typical framework
Market orders only
manifoldbt
Market, limit, stop, stop-limit, market-if-touched, stop-loss, take-profit, trailing stop
Reproducibility
Typical framework
Depends on random seeds and data snapshots
manifoldbt
Deterministic bit-for-bit replay via cryptographic manifests

Data connectors

Built-in providers fetch and normalize market data into Arrow IPC. Parallel ingestion with progress tracking, import from any source.

Crypto exchanges

Binance logoBinance

Spot & perpetuals

spotperpetuals
Bybit logoBybit

Spot & perpetuals

spotperpetuals
Hyperliquid logoHyperliquid

Perpetuals L1

perpetuals
dYdX logodYdX

Perpetuals v4 (decentralized)

perpetuals
Bitstamp logoBitstamp

Spot, BTC, ETH, EUR & USD pairs

spot
Deribit logoDeribit

BTC & ETH options, futures and perpetuals

optionsfuturesperpetualsspot

Stocks, futures, FX and indices

Massive and Databento go down to tick. Yahoo and IEX are landing next, free and daily.

Yahoo Finance logoYahoo Finance

Stocks, ETFs, futures, FX, indices. Daily bars, back to 1970.

equitiesfuturesforexindices
IEX
Soon

US equities and ETFs, IEX exchange tape

equitiesindices
Massive logoMassive
Pro

Stocks, ETFs, futures, options, forex, and crypto spot

equitiesoptionsfuturesforexindicesspot
Databento logoDatabento
Pro

CME, NASDAQ, OPRA, tick to daily

equitiesoptionsfuturesindices
CSV / DataFrame import, auto-detected format
MetaTrader 4Native CSV export
MetaTrader 5Native CSV/TSV export
Custom CSVtimestamp, OHLCV
DataFramepandas or Polars, in memory

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 →

<200ms
Single-shot backtest, 1 year of 1-min bars
552K combos
2D heatmap generated in seconds
All cores
Parallel sweeps, walk-forward & Monte Carlo via Rayon
bt.plot.heatmap_2d(sweep, metric="t-stat(alpha)")
Parameter sweep heatmap, Sharpe ratio by period × num_std

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 reference

Five turns, four of them reading an error back. What finally runs carries whatever the compiler cannot see.

  1. youadd a regime filter to my ETH strategy using BTC's trend
  2. claudewriting strategy.py
  3. engineerror: 'close' is not callable
  4. claudefixing
  5. engineerror: chained comparisons (a < b < c) are not supported
  6. claudefixing
  7. engineerror: SymbolRef requires orchestrator-level handling
  8. claudefixing
  9. engineerror: empty bar dataset
  10. claudefixing
  11. engineok, 1,412 trades
  12. #runs. BTC is read one bar early; nothing raised.

manifoldbt + MCP

mcp.manifoldbt.com

One lookup, one draft. The rules the compiler enforces arrive before the code is written, not after.

  1. youadd a regime filter to my ETH strategy using BTC's trend
  2. claudesearch_docs("reference another symbol")
  3. mcpCross-Asset References, symbol_ref(), a worked example. 64 ms.
  4. claudewriting strategy.py
  5. engineok, 1,388 trades
  6. #runs, first try. warmup_bars set, symbol_ref() inside the signal.
5 → 2
Turns to a strategy that runs. The first draft compiles.
-90%
Quiet bugs: look-ahead, a NaN read as a position, sizing off by a bar.
~40x
Less context than pasting the guide. One lookup, one section, 64 ms.

Connect the MCP server →

Research tools

Pro

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

bt.plot.walk_forward(wf, mode="bars")
Walk-forward, IS vs OOS Sharpe per fold
bt.plot.walk_forward(wf, mode="stitched", full_result=result)
Stitched OOS equity vs full backtest

Monte Carlo analysis

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

bt.plot.monte_carlo(result, method="bootstrap")
Monte Carlo bootstrap, fan chart with P(ruin)

Safety checks

Pro

Automated 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 ok
Signal 'slow' no future data ok
Signal 'rsi' no future data ok
Signal 'entry' no future data ok
Position sizing no future data ok
 
Result: 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% ok
Exposure drift, window 2: 0.8% ok
Regime sensitivity: stable across 3 windows
 
Result: 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.

Community
Free
Full engine, no time limit
pip install manifoldbt
  • 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
Pro
$19/mo
Unlock Rust-optimized research tools
  • 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
TeamEarly access
$299/mo
Managed compute and hosted data
  • 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.

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.

$pip install manifoldbt
See the benchmark →