A vectorbt alternative built on Rust

vectorbt is an excellent, mature library for vectorized backtesting in Python. If you are weighing it against Manifold-BT, the real question is how your strategy is shaped: vectorized and signal-heavy, or path-dependent with stops and fills. Here is the honest comparison.

Where the two are built differently

vectorbt expresses the whole backtest as operations over NumPy arrays, signals and execution alike. That is extremely fast for signal research and sweeping huge grids of simple rules, and it fits naturally if you already think in pandas.

Manifold-BT evaluates signals the same vectorized way, over the full series in Rust, then runs execution through an event-driven loop. That keeps the speed, years of bars in sub-second, while handling path-dependent logic, stop-losses, take-profits, partial fills, inventory, that is cumbersome to vectorize. It also models execution realistically by default: market-impact slippage, funding, and next-bar fills.

Side by side

 Manifold-BTvectorbt
Core engineRust: vectorized signals, event-driven executionNumPy / Numba, vectorized
SpeedSub-second on years of barsVery fast on vectorized array ops
Path-dependent logicFirst-class (stops, partial fills, inventory)Awkward, often needs manual workarounds
Execution realismMarket-impact slippage, funding, partial fills, signal delaySimplified; costs as flat parameters
Parameter searchParallel sweeps, 2-D heatmaps, walk-forwardVectorized parameter grids
Live tradingNo, research onlyNo, research only
API styleExpression DSL, no pandas requiredPandas / NumPy-centric
Best forRealistic, path-dependent research at speedLarge-scale vectorized factor research

The same sweep, with realism intact

Here is a parallel parameter sweep in Manifold-BT. Unlike a vectorized sweep, every combination is evaluated through the full event-driven engine, so stops and realistic fills apply to each one, with no loss of speed:

sweep.py
import manifoldbt as mbt
from manifoldbt.indicators import close, ema
from manifoldbt.helpers import time_range, Slippage, Interval

fast_p = mbt.param("fast", default=20)
slow_p = mbt.param("slow", default=50)
fast, slow = ema(close, fast_p), ema(close, slow_p)
strategy = (
    mbt.Strategy.create("ema")
    .signal("fast", fast)
    .signal("slow", slow)
    .size(mbt.when(fast > slow, 1.0, 0.0))
)

start, end = time_range("2021-01-01", "2026-01-01")
config = mbt.BacktestConfig(
    universe={"binance": ["BTCUSDT"]},
    time_range_start=start,
    time_range_end=end,
    bar_interval=Interval.hours(1),
    initial_capital=10_000,
    fees=mbt.FeeConfig.binance_perps(),
    slippage=Slippage.fixed_bps(2),
    warmup_bars=50,
)
store = mbt.ingest(provider="binance", symbol="BTCUSDT", symbol_id=1,
                   interval="1h", start="2021-01-01T00:00:00Z",
                   end="2026-01-01T00:00:00Z")

# Sweep the whole grid in parallel on Rust, with stops and realistic fills intact
sweep = mbt.run_sweep(
    strategy,
    param_grid={"fast": [10, 20, 30], "slow": [50, 100, 150]},
    config=config,
    store=store,
)
print(sweep.best("sharpe"))

Which should you pick?

Choose vectorbt for large-scale vectorized factor and signal research where simple entry/exit rules dominate. Choose Manifold-BT when path-dependent logic and realistic execution matter, crypto perpetuals with funding, strategies with stops and partial fills, or anything where the gap between the backtest and the fill is what decides profitability.

Keep reading

Run your first backtest

Install Manifold-BT and reproduce the backtest above in seconds. The Rust core runs years of bars sub-second so you can sweep parameters instead of waiting.

$pip install manifoldbt