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-BT | vectorbt | |
|---|---|---|
| Core engine | Rust: vectorized signals, event-driven execution | NumPy / Numba, vectorized |
| Speed | Sub-second on years of bars | Very fast on vectorized array ops |
| Path-dependent logic | First-class (stops, partial fills, inventory) | Awkward, often needs manual workarounds |
| Execution realism | Market-impact slippage, funding, partial fills, signal delay | Simplified; costs as flat parameters |
| Parameter search | Parallel sweeps, 2-D heatmaps, walk-forward | Vectorized parameter grids |
| Live trading | No, research only | No, research only |
| API style | Expression DSL, no pandas required | Pandas / NumPy-centric |
| Best for | Realistic, path-dependent research at speed | Large-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:
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.