VectorBT PRO v2026.9.5 includes native Rust simulators, streaming indicators, and portfolio continuation. Explore features

Financial data is multidimensional. Your research engine should be too.

Analyze market data and test trading ideas at any scale with one flexible toolkit. Build indicators and signals, simulate and optimize portfolios, validate strategies across time and market conditions, and understand every result without giving up control of your workflow.

Architected and built by Oleg Polakow, senior software engineer and original creator of VectorBT.

  • 8 years

    In development

    VectorBT has evolved continuously since 2017

  • 8.7k

    OSS GitHub stars

    Across the open-source VectorBT repository

  • 510k+

    Monthly OSS downloads

    Open-source VectorBT downloads from PyPI

  • 65k+

    Community messages

    Archived across 15 topic channels

Workflow

A foundation for any quantitative trading workflow.

Acquire and align data, build indicators and signals, simulate portfolios, validate across time and parameters, and analyze the result through one connected workflow.

  1. Data

    Connect, cache, transform, combine, and stream local and remote market data

  2. Indicators

    Build, search, stream with stateful accumulators, parallelize, and visualize indicator and signal pipelines

  3. Portfolio

    Model orders, signals, leverage, stops, limits, cash flows, and simulation callbacks

  4. Optimization

    Explore parameter spaces with cross-validation, conditional grids, and portfolio optimizers

  5. Analysis

    Inspect trades, patterns, projections, benchmarks, and excursion metrics

Capabilities across every stage:

Philosophy

Built for people who want control over the workflow.

VBT is a composable toolkit, not a fixed pipeline. Use ready-made components, replace any stage with your own code, or work directly with the underlying functions and kernels.

VBT is not

  • No-code strategy builder
  • Hosted trading bot
  • Strategy marketplace
  • Framework that controls your workflow

With VBT

  • Bring your own data, models, and execution
  • Choose high-level components for convenience or the underlying functions and kernels for control and performance
  • Explore many instruments, parameters, and scenarios at once
  • Inspect, combine, and reuse intermediate results
  • Scale functions with parameterization, chunking, and parallel/distributed execution
  • Work in Python, call Rust from Python, or build in native Rust
  • Give AI coding agents full freedom

Validation

Explore robustness, not just the best result.

VBT keeps parameter exploration and validation in the same workflow, so promising performance can be tested across configurations, periods, and market conditions.

Validate across time

Use rolling, expanding, walk-forward, purged, and combinatorial splits to measure behavior beyond one historical window.

Inspect parameter surfaces

Compare neighborhoods and complete result surfaces instead of reducing the search to one winning configuration.

Compare every split

Apply the same analytics to in-sample and out-of-sample results to understand where performance persists or breaks down.

One pipeline evaluates 6,475 parameter pairs across 24 rolling train/test splits, generating all 310,800 results in under a minute on an Apple M3. Each heatmap cell shows how consistently its in-sample Sharpe ratio carries into the next out-of-sample period.

@vbt.cv_split(  
    splitter="from_n_rolling",  
    splitter_kwargs=dict(
        n=24, length=720,
        split=0.75, set_labels=["train", "test"],
    ),
    parameterized_kwargs=dict(
        mono_chunk_len=128,
        execute_kwargs=dict(chunk_len="auto", engine="threadpool"),
    ),
    return_grid="all",
)
def sma_crossover_sharpe(  
    close: vbt.Takeable,
    fast_window: vbt.Param(
        condition="fast_window < slow_window",
        mono_merge_func="concat",
    ),
    slow_window: vbt.Param(mono_merge_func="concat"),
) -> vbt.MergeFunc("concat"):
    fast_ma = vbt.MA.run(close, fast_window, hide_params=True)
    slow_ma = vbt.MA.run(close, slow_window, hide_params=True)
    entries = fast_ma.ma_crossed_above(slow_ma)
    exits = fast_ma.ma_crossed_below(slow_ma)
    return vbt.PF.from_signals(close, entries, exits).sharpe_ratio
Heatmap of train-to-test Sharpe ratio correlation for moving-average crossover parameters across 24 rolling BTC-USD splits Figure data (JSON)

Capabilities

One connected quantitative research toolkit.

A broad set of composable capabilities covers the path from acquiring data to validating and analyzing portfolios.

Data sources and adapters
20+
Remote, local, database, and synthetic data
Indicators, signals, and labels
500+
Built in, generated, and integrated
Cross-validation factories
10+
Including purged and walk-forward methods
Portfolio optimization factories
10
From allocation functions to integrated optimizers
Portfolio simulation factories
8
Unique behavior across Numba and Rust
Metrics
200+
Across portfolios, records, and statistical integrations
Plot types
90+
Reusable visual analysis across VBT objects
Jitting backends
3
Numba, NumPy, and Rust
Execution engines
7
Serial, local parallel, and distributed execution

Execution

One Python workflow, two low-level compute backends.

Each example below runs the same moving-average crossover pipeline. Python provides the high-level composition and convenience layer, while Numba and Rust expose the underlying indicator, signal, simulation, and returns APIs. Rust is also available as an independent native crate.

Python workflow

Compose data, indicators, signals, portfolios, optimization, and analysis through one expressive API. Python manages configuration, parameterization, metadata, and results, then dispatches computational work to a low-level compute backend.

data = vbt.YFData.pull("BTC-USD")
fast_ma = data.run("vbt:ma", window=20, hide_params=True)
slow_ma = data.run("vbt:ma", window=50, hide_params=True)

entries = fast_ma.ma_crossed_above(slow_ma)
exits = fast_ma.ma_crossed_below(slow_ma)

pf = vbt.PF.from_signals(data, entries, exits)
sharpe = pf.sharpe_ratio

Compute backends

Numba backend

Write numerical kernels in Python and compile supported code at runtime to native machine code with C-like performance.

Use it through the high-level workflow, or call its kernels directly when lower-level control is useful.

close = vbt.to_2d_array(data.close)
fast_ma = vbt.nb.ma_nb(close, 20)
slow_ma = vbt.nb.ma_nb(close, 50)
entries = vbt.nb.crossed_above_nb(fast_ma, slow_ma)
exits = vbt.nb.crossed_above_nb(slow_ma, fast_ma)

sim_out = vbt.pf_nb.from_signals_nb(
    target_shape=close.shape,
    group_lens=np.full(close.shape[1], 1),
    close=close,
    long_entries=entries,
    long_exits=exits,
    save_returns=True,
)
sharpe = vbt.ret_nb.sharpe_ratio_nb(
    sim_out.in_outputs.returns,
    ann_factor=365,
)

Rust backend

An independent native crate that can also serve as an optional, ahead-of-time compiled compute backend for Python.

Use it directly from Rust, or let compatible Python operations dispatch to it without changing the high-level workflow.

let fast_ma = ma().close(close.view()).window(20).call()?;
let slow_ma = ma().close(close.view()).window(50).call()?;
let entries = crossed_above().arr1(fast_ma.view()).arr2(slow_ma.view()).call()?;
let exits = crossed_above().arr1(slow_ma.view()).arr2(fast_ma.view()).call()?;

let group_lens = Array1::<i64>::ones(close.ncols());
let sim_out = from_signals()
    .target_shape(close.dim())
    .group_lens(group_lens.view())
    .close(close.view())
    .long_entries(entries.view())
    .long_exits(exits.view())
    .save_returns(true)
    .call()?;
let sharpe = sharpe_ratio_1d()
    .returns(sim_out.in_outputs.returns.column(0))
    .ann_factor(365.0)
    .call();

Performance

Compare simulation throughput.

Higher is better. High-level covers the full portfolio workflow, mid-level runs the simulation with prepared inputs, and low-level processes each order directly.

Benchmark packageDownload ZIP

1,000,000 one-minute bars and 1,388 filled orders per column.

High-level
320M bars/s
25 ms for this workload
Mid-level
579M bars/s
14 ms for this workload, 1.8x high-level
Low-level
4.7B bars/s
1.7 ms for this workload, 14.6x high-level
Sparse simulator benchmarks at 1,000,000 rows per column
SimulatorVersionModeStatusColumnsWarm throughput (M bars/s)First-call throughput (M bars/s)Warm runtime (s)First-call runtime (s)Compilation (s)
PRO low-level Rust2026.6.27ParallelCompleted84665.7432383174160.001714625
PRO low-level Numba2026.6.27ParallelCompleted84163.32302204300052.1160832578238130.001921541988849643.78056958317756653.778648041188717
PRO low-level Rust2026.6.27SerialCompleted11424.92362409374850.000701792
PRO low-level Numba2026.6.27SerialCompleted11226.99398639811830.3510514305229050.00081499991938471792.848585458006712.847770458087325
PRO mid-level Rust2026.6.27ParallelCompleted8579.3830034519640.013807792
PRO high-level Rust2026.6.27ParallelCompleted8319.61061352701010.025030457880347967
Manifold-BT0.19.0ParallelCompleted8190.962690664311480.041893
PRO mid-level Rust2026.6.27SerialCompleted1112.248676616164870.008908791
Manifold-BT0.19.0SerialCompleted1109.292100286482350.0091497921384871
PRO mid-level Numba2026.6.27ParallelCompleted8103.393794030940540.51608457685265530.0773740829899907115.5013351663947115.42396108340472
PRO high-level Numba2026.6.27ParallelCompleted895.374864984275660.50732255504796010.0838795420713722715.76906037470325815.685180832631886
PRO high-level Rust2026.6.27SerialCompleted182.131868413456840.012175541836768389
PRO mid-level Numba2026.6.27SerialCompleted171.250019799195840.085270530565565190.01403508381918072711.7273809998296211.71334591601044
PRO high-level Numba2026.6.27SerialCompleted154.482551433632680.083487449425977150.0183545001782476911.9778482499532411.959493749774992
OSS Numba1.1.0SerialCompleted121.4367055113375960.336708461622389930.0466489591635763652.9699283326044682.9232793734408915
RaptorBT0.9.0SerialCompleted120.8650112491686350.04792712489143014
Nautilus Python v22.0.0rc3SerialCompleted10.70778919939286541.412850041873753
Nautilus Rust v20.62.0SerialCompleted10.59317887301501031.6858321250000001
Backtrader1.9.78.123ParallelCompleted80.1228447802245134965.12283212505281
PyBroker Numba2.0.0SerialCompleted10.081236121315575770.0739374233395184612.30979500012472313.5249506249092521.2151556247845292
Backtrader1.9.78.123SerialCompleted10.02062187072788773348.49220583308488
Horizontal ranking of sparse simulator benchmarks at 1,000,000 rows per column by warm bar throughput, with first-call throughput shown as a translucent marker

Environment: Apple M3 (8 logical cores), arm64, macOS 26.5.2

Architecture

A consistent model from composition to execution.

You control the workflow while VBT carries the repetitive engineering across data alignment, array preparation, compiled execution, persistence, and analysis.

Multidimensional by design

Broadcasting, indexing, grouping, and wrapping preserve instruments, time frames, parameters, and scenarios throughout the workflow.

Scale the same workflow

Parameterize, chunk, cache, and distribute work across supported execution engines without changing the research model.

Inspect and resume

Keep intermediate objects available for analysis, continue simulations from saved state, and process long histories incrementally.

Source code

Built to be inspected, extended, and understood.

VectorBT has been architected and maintained by Oleg Polakow, its original creator and a senior software engineer, since 2017. VectorBT PRO has continued that architectural direction since 2021, shaped by community feedback and demanding quantitative workflows.

Membership includes source access, so you can inspect the implementation, trace a result through each layer, and adapt individual components to your data and infrastructure. Shared conventions keep those components predictable to use and practical to extend.

The MCP server, CLI, LLM-ready documentation, and agent tools make the same codebase easier for people and coding agents to navigate, explain, and automate.

Crowdfunding

Built for the community, funded by its members.

VectorBT PRO is an independent crowdfunding initiative. Membership revenue funds the infrastructure, software subscriptions, AI tokens, development, maintenance, and other resources that keep the project moving forward.

Community feedback

Loved by people who build with it.

Rewritten from recurring praise shared in Discord. Details are mixed to keep individual messages private.

this thing is ridiculously fast

First run compiled. After that, millions of rows were done in seconds. Had to check I had not accidentally skipped half the data.

Anonymous community member

bit of a learning curve, honestly

NumPy and broadcasting took me a while. Once I stopped trying to make VBT behave like the other backtesters I had used, it started to click.

There are things I can test now that I would not even know how to set up in those tools.

Anonymous community member

I keep thinking something is missing

Then I search the docs properly and there it is. Usually with an example.

The documentation is huge, but finding things gets easier once you know how it is organised.

Anonymous community member

yep, that fixed it

Spent ages changing the index and reshaping everything. The actual problem was tiny. One reply pointed it out and the backtest ran.

Anonymous community member

mostly lurking here

I rarely post, but someone will ask the exact question I could not put into words. Then the replies send me off to try something new.

Reading this Discord has become part of learning VBT for me.

Anonymous community member

Joined for the backtesting

Now I somehow have parameter grids, custom indicators, portfolio optimization, and lower-level functions in the same project.

There is always another part of VBT I have not explored yet.

Anonymous community member

Get complete access to VectorBT PRO.

Membership includes the complete source, private documentation and API references, tutorials, cookbook recipes, release notes, ongoing updates, and the private Discord community.