{"repo":"polakowo/vectorbt","free":true,"listed":false,"github":"https://github.com/polakowo/vectorbt","clone":"git clone https://github.com/polakowo/vectorbt.git","description":"The backtesting engine that gives you an unfair advantage. Run thousands of trading ideas before others finish one.","language":"Python","stars":8704,"topics":["algorithmic-trading","algorithmic-traiding","backtesting","cryptocurrency","data-science","data-visualization","finance","machine-learning","portfolio-optimization","quantitative-analysis","quantitative-finance","time-series","trading","trading-strategies"],"license":null,"category":"quant_finance","readme_excerpt":"<div align=\"center\">\n    <a href=\"https://vectorbt.pro/\" title=\"VectorBT PRO\">\n        <img src=\"https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/logo/header-pro.svg\" />\n    </a>\n</div>\n<div align=\"center\">\n    <a href=\"https://vectorbt.dev/\" title=\"vectorbt\">\n        <img src=\"https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/logo/header.svg\" />\n    </a>\n</div>\n\n<br>\n\n<p align=\"center\">\n    <a href=\"https://pepy.tech/project/vectorbt\" title=\"Downloads\">\n        <img src=\"https://img.shields.io/pepy/dt/vectorbt?label=downloads&color=blue\" />\n    </a>\n    <a href=\"https://pypi.org/project/vectorbt\" title=\"PyPI\">\n        <img src=\"https://img.shields.io/pypi/v/vectorbt\" />\n    </a>\n    <a href=\"https://pypi.org/project/vectorbt\" title=\"Supported Python versions\">\n        <img src=\"https://img.shields.io/pypi/pyversions/vectorbt\" />\n    </a>\n    <a href=\"https://hub.docker.com/r/polakowo/vectorbt\" title=\"Docker image version\">\n        <img src=\"https://img.shields.io/docker/v/polakowo/vectorbt?sort=semver&label=docker&color=2496ed&logo=docker&logoColor=white\" />\n    </a>\n    <a href=\"https://hub.docker.com/r/polakowo/vectorbt\" title=\"Docker pulls\">\n        <img src=\"https://img.shields.io/docker/pulls/polakowo/vectorbt?label=docker%20pulls&color=2496ed&logo=docker&logoColor=white\" />\n    </a>\n    <a href=\"https://github.com/polakowo/vectorbt/actions/workflows/tests.yml\" title=\"Tests\">\n        <img src=\"https://img.shields.io/github/actions/workflow/status/polakowo/vectorbt/tests.yml?branch=master&label=tests&logo=githubactions&logoColor=white\" />\n    </a>\n    <a href=\"https://github.com/polakowo/vectorbt/actions/workflows/pypi.yml\" title=\"PyPI release\">\n        <img src=\"https://img.shields.io/github/actions/workflow/status/polakowo/vectorbt/pypi.yml?label=release&logo=githubactions&logoColor=white\" />\n    </a>\n    <a href=\"https://vectorbt.dev/\" title=\"Website\">\n        <img src=\"https://img.shields.io/website?url=https%3A%2F%2Fvectorbt.dev%2F&label=website\" />\n    </a>\n    <a href=\"https://pypi.org/project/vectorbt-rust\" title=\"Rust engine\">\n        <img src=\"https://img.shields.io/pypi/v/vectorbt-rust?label=rust%20engine&color=dea584&logo=rust\" />\n    </a>\n    <a href=\"https://github.com/polakowo/vectorbt/blob/master/LICENSE.md\" title=\"License\">\n        <img src=\"https://img.shields.io/badge/license-Fair%20Code-yellow\" />\n    </a>\n</p>\n\n<h3 align=\"center\"><b>Thinks in matrices, backtests at scale.</b></h3>\n\n<p align=\"center\">VectorBT takes a radically different approach to backtesting: instead of looping through bars one strategy at a time, it packs thousands of configurations into NumPy arrays, accelerates the hot path with Numba and Rust, and runs them all at once, turning hours of grid search into seconds.</p>\n\n---\n\nExplore thousands of trading ideas across assets and timeframes, analyze portfolio performance down to individual trades, and visualize results interactively, all in a few lines of code. Built for both human researchers and AI agents, VectorBT combines large-scale experimentation with a mature, battle-tested backtesting stack refined through years of community use.\n\nVectorBT is the open-source community edition of [VectorBT PRO](https://vectorbt.pro/), a state-of-the-art hybrid backtesting library.\n\n## Features\n\n- **Fast, vectorized backtesting** and strategy research built on pandas, NumPy, and Numba\n- **Optional Rust engine** for precompiled speed without JIT overhead\n- **Pandas-native API** with custom accessors and high-performance operations\n- **Flexible broadcasting** for multi-asset analysis and large-scale parameter sweeps\n- **Rich indicator ecosystem** with custom indicators and integrations for TA-Lib, Pandas TA, and more\n- **Portfolio backtesting** with trade, drawdown, and performance analytics, including QuantStats integration\n- **Signal tooling** for generation, ranking, mapping, and distribution analysis\n- **Built-in data access** with preprocessing and synthetic data generation\n- **Robustness testing** with walk-forward optimization and label generation for ML workflows\n- **Interactive visualization** with Plotly, Jupyter widgets, and browser-friendly dashboards\n- **Automation tools** for scheduled updates and Telegram notifications\n- **Composable Python API** for rapid experimentation and AI agent-driven workflows\n\n## Installation\n\n```sh\npip install -U vectorbt\n```\n\nTo install the optional Rust engine:\n\n```sh\npip install -U \"vectorbt[rust]\"\n```\n\nTo install all optional integrations (TA-Lib, Pandas TA, etc.):\n\n```sh\npip install -U \"vectorbt[full]\"\n```\n\nTo install all optional integrations together with the Rust engine:\n\n```sh\npip install -U \"vectorbt[full,rust]\"\n```\n\n## Examples\n\n### Invest $100 in Bitcoin since 2014\n\n```python\nimport vectorbt as vbt\n\ndata = vbt.YFData.download(\"BTC-USD\")\nprice = data.get(\"Close\")\n\npf = vbt.Portfolio.from_holding(price, init_cash=100)\nprint(pf.total_profit())\n```\n\n```plaintext\n19501.10906763755\n```\n\n### Trade a dual-SMA crossover strategy\n\n```python\nfast_ma = vbt.MA.run(price, 10)\nslow_ma = vbt.MA.run(price, 50)\nentries = fast_ma.ma_crossed_above(slow_ma)\nexits = fast_ma.ma_crossed_below(slow_ma)\n\npf = vbt.Portfolio.from_signals(price, entries, exits, init_cash=100)\nprint(pf.total_profit())\n```\n\n```plaintext\n34417.80960086067\n```\n\n### Generate 1,000 random strategies\n\n```python\nimport numpy as np\n\nsymbols = [\"BTC-USD\", \"ETH-USD\"]\ndata = vbt.YFData.download(symbols, missing_index=\"drop\")\nprice = data.get(\"Close\")\n\nn = np.random.randint(10, 101, size=1000).tolist()\npf = vbt.Portfolio.from_random_signals(price, n=n, init_cash=100, seed=42)\n\nmean_expectancy = pf.trades.expectancy().groupby([\"randnx_n\", \"symbol\"]).mean()\nfig = mean_expectancy.unstack().vbt.scatterplot(xaxis_title=\"randnx_n\", yaxis_title=\"mean_expectancy\")\nfig.show()\n```\n\n![](https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/images/usage_rand_scatter.svg)\n\n### Test 10,000 dual-SMA window combinations\n\n```python\nsymbols = [\"BTC-USD\", \"ETH-USD\", \"XRP-USD\"]\ndata = vbt.YFData.download(symbols, missing_index=\"drop\")\nprice = data.get(\"Close\")\n\nwindows = np.arange(2, 101)\nfast_ma, slow_ma = vbt.MA.run_combs(price, window=windows, r=2, short_names=[\"fast\", \"slow\"])\nentries = fast_ma.ma_crossed_above(slow_ma)\nexits = fast_ma.ma_crossed_below(slow_ma)\n\npf = vbt.Portfolio.from_signals(price, entries, exits, size=np.inf, fees=0.001, freq=\"1D\")\n\nfig = pf.total_return().vbt.heatmap(\n    x_level=\"fast_window\", y_level=\"slow_window\", slider_level=\"symbol\", symmetric=True,\n    trace_kwargs=dict(colorbar=dict(title=\"Total return\", tickformat=\"%\")))\nfig.show()\n```\n\n<img width=\"750\" src=\"https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/images/usage_dmac_heatmap.gif\">\n\n### Inspect any strategy configuration\n\n```python\nprint(pf[(10, 20, \"ETH-USD\")].stats())\n```\n\n```plaintext\nStart                          2017-11-09 00:00:00+00:00\nEnd                            2026-01-03 00:00:00+00:00\nPeriod                                2978 days 00:00:00\nStart Value                                        100.0\nEnd Value                                    1604.093789\nTotal Return [%]                             1504.093789\nBenchmark Return [%]                          866.094127\nMax Gross Exposure [%]                             100.0\nTotal Fees Paid                               204.226289\nMax Drawdown [%]                               70.734951\nMax Drawdown Duration                 1095 days 00:00:00\nTotal Trades                                          81\nTotal Closed Trades                                   80\nTotal Open Trades                                      1\nOpen Trade PnL                                -14.232533\nWin Rate [%]                                       41.25\nBest Trade [%]                                120.511071\nWorst Trade [%]                               -27.772271\nAvg Winning Trade [%]                          27.265519\nAvg Losing Trade [%]                           -9.022864\nAvg Winning Trade Duration    32 days 20:21:49.090909091\nAvg Losing Trade Duration      8 days 16:51:03.829787234\nProfit Factor                                   1.275515\nExpectancy                                     18.979079\nSharpe Ratio                                    0.861945\nCalmar Ratio                                    0.572758\nOmega Ratio                                      1.20277\nSortino Ratio                                   1.301377\nName: (10, 20, ETH-USD), dtype: object\n```\n\n### Plot any strategy configuration\n\n```python\npf[(10, 20, \"ETH-USD\")].plot().show()\n```\n\n![](https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/images/usage_dmac_portfolio.svg)\n\n### Animate Bollinger Bands across multiple symbols\n\nVectorBT goes beyond backtesting, with tools for financial data analysis and visualization:\n\n```python\nsymbols = [\"BTC-USD\", \"ETH-USD\", \"XRP-USD\"]\ndata = vbt.YFData.download(symbols, period=\"6mo\", missing_index=\"drop\")\nprice = data.get(\"Close\")\nbbands = vbt.BBANDS.run(price)\n\ndef plot(index, bbands):\n    bbands = bbands.loc[index]\n    fig = vbt.make_subplots(\n        rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.15,\n        subplot_titles=(\"%B\", \"Bandwidth\"))\n    fig.update_layout(showlegend=False, width=750, height=400)\n    bbands.percent_b.vbt.ts_heatmap(\n        trace_kwargs=dict(zmin=0, zmid=0.5, zmax=1, colorscale=\"Spectral\", colorbar=dict(\n            y=(fig.layout.yaxis.domain[0] + fig.layout.yaxis.domain[1]) / 2, len=0.5\n        )), add_trace_kwargs=dict(row=1, col=1), fig=fig)\n    bbands.bandwidth.vbt.ts_heatmap(\n        trace_kwargs=dict(colorbar=dict(\n            y=(fig.layout.yaxis2.domain[0] + fig.layout.yaxis2.domain[1]) / 2, len=0.5\n        )), add_trace_kwargs=dict(row=2, col=1), fig=fig)\n    return fig\n\nvbt.save_animation(\"bbands.gif\", bbands.wrapper.index, plot, bbands, delta=90, step=3, fps=3)\n```\n\n```plaintext\n100%|██████████| 31/31 [00:21<00:0","default_branch":"master","files":297,"tree":[".coveragerc",".gitattributes",".github/FUNDING.yml",".github/workflows/docker.yml",".github/workflows/docs.yml",".github/workflows/pypi.yml",".github/workflows/tests.yml",".gitignore","Dockerfile","LICENSE.md","MANIFEST.in","README.md","apps/candlestick-patterns/Dockerfile","apps/candlestick-patterns/Procfile","apps/candlestick-patterns/README.md","apps/candlestick-patterns/app.py","apps/candlestick-patterns/assets/default.css","apps/candlestick-patterns/assets/favicon.ico","apps/candlestick-patterns/assets/screenshot.png","apps/candlestick-patterns/assets/style.css","apps/candlestick-patterns/assets/teaser.png","apps/candlestick-patterns/requirements.txt","benchmarks/BENCHMARKS.md","benchmarks/BENCHMARKS_NUMBA.md","benchmarks/BENCHMARKS_RUST.md","benchmarks/README.md","benchmarks/bench_engine.py","benchmarks/bench_matrix.py","conftest.py","docs/LICENSE.md","docs/README.md","docs/docs/CNAME","docs/docs/assets/images/ATR.svg","docs/docs/assets/images/BBANDS.svg","docs/docs/assets/images/Bar.svg","docs/docs/assets/images/Bar_updated.svg","docs/docs/assets/images/Box.svg","docs/docs/assets/images/Gauge.svg","docs/docs/assets/images/Heatmap.svg","docs/docs/assets/images/Histogram.svg","docs/docs/assets/images/IndicatorFactory_plots.svg","docs/docs/assets/images/MA.svg","docs/docs/assets/images/MACD.svg","docs/docs/assets/images/MSTD.svg","docs/docs/assets/images/MyInd_plot.svg","docs/docs/assets/images/OBV.svg","docs/docs/assets/images/OHLCSTX.svg","docs/docs/assets/images/RSI.svg","docs/docs/assets/images/STOCH.svg","docs/docs/assets/images/Scatter.svg","docs/docs/assets/images/Volume.svg","docs/docs/assets/images/basic_price.svg","docs/docs/assets/images/context_info.png","docs/docs/assets/images/data_plot.svg","docs/docs/assets/images/data_plots.svg","docs/docs/assets/images/df_barplot.svg","docs/docs/assets/images/df_boxplot.svg","docs/docs/assets/images/df_heatmap.svg","docs/docs/assets/images/df_histplot.svg","docs/docs/assets/images/df_lineplot.svg","docs/docs/assets/images/df_plot.svg","docs/docs/assets/images/df_scatterplot.svg","docs/docs/assets/images/drawdowns_plot.svg","docs/docs/assets/images/drawdowns_plots.svg","docs/docs/assets/images/expanding_split_plot.svg","docs/docs/assets/images/features_qs_plot_snapshot.png","docs/docs/assets/images/features_scheduler.svg","docs/docs/assets/images/from_order_func_g1.svg","docs/docs/assets/images/from_order_func_g2.svg","docs/docs/assets/images/generic_plots.svg","docs/docs/assets/images/index_by_any.svg","docs/docs/assets/images/index_by_symbol.svg","docs/docs/assets/images/mapped_boxplot.svg","docs/docs/assets/images/mapped_to_pd_plot.svg","docs/docs/assets/images/ohlcv_plot.svg","docs/docs/assets/images/ohlcv_plots.svg","docs/docs/assets/images/orders_plot.svg","docs/docs/assets/images/orders_plots.svg","docs/docs/assets/images/plot_cumulative.svg","docs/docs/assets/images/portfolio_plot.svg","docs/docs/assets/images/portfolio_plot_custom.svg","docs/docs/assets/images/portfolio_plot_drawdowns.svg","docs/docs/assets/images/portfolio_plot_path.svg","docs/docs/assets/images/portfolio_plot_snapshot.png","docs/docs/assets/images/portfolio_value.svg","docs/docs/assets/images/px_bar.svg","docs/docs/assets/images/range_split_plot.svg","docs/docs/assets/images/ranges_plot.svg","docs/docs/assets/images/ranges_plots.svg","docs/docs/assets/images/signals_df_plot.svg","docs/docs/assets/images/signals_plot_as_markers.svg","docs/docs/assets/images/simulate_nb.gif","docs/docs/assets/images/simulate_nb.svg","docs/docs/assets/images/simulate_row_wise_nb.gif","docs/docs/assets/images/split_plot.svg","docs/docs/assets/images/sr_heatmap.svg","docs/docs/assets/images/sr_heatmap_slider.gif","docs/docs/assets/images/sr_overlay_with_heatmap.svg","docs/docs/assets/images/sr_plot_against.svg","docs/docs/assets/images/sr_qqplot.svg","docs/docs/assets/images/sr_volume.svg","docs/docs/assets/images/trades_plot.svg","docs/docs/assets/images/trades_plot_pnl.svg","docs/docs/assets/images/trades_plots.svg","docs/docs/assets/images/usage_bbands.gif","docs/docs/assets/images/usage_dmac_heatmap.gif","docs/docs/assets/images/usage_dmac_portfolio.svg","docs/docs/assets/images/usage_rand_scatter.svg","docs/docs/assets/interactive/features_gbm_data.html","docs/docs/assets/interactive/features_golden_crossover.html","docs/docs/assets/interactive/features_local_extrema.html","docs/docs/assets/interactive/features_plot_against.html","docs/docs/assets/interactive/features_portfolio_plot.html","docs/docs/assets/interactive/features_rolling_split.html","docs/docs/assets/interactive/features_top_drawdowns.html","docs/docs/assets/interactive/features_volume.html","docs/docs/assets/javascripts/extra.js","docs/docs/assets/logo/apple-touch-icon.png","docs/docs/assets/logo/favicon-96x96.png","docs/docs/assets/logo/favicon.ico","docs/docs/assets/logo/favicon.svg","docs/docs/assets/logo/header-pro.svg","docs/docs/assets/logo/header.svg","docs/docs/assets/logo/logo-white.svg","docs/docs/assets/logo/logo.svg","docs/docs/assets/logo/site.webmanifest","docs/docs/assets/logo/web-app-manifest-192x192.png","docs/docs/assets/logo/web-app-manifest-512x512.png","docs/docs/assets/misc/AlgoTradingCookbook.jpg","docs/docs/assets/stylesheets/extra.css","docs/docs/context7.json","docs/docs/getting-started/contributing.md","docs/docs/getting-started/features.md","docs/docs/getting-started/installation.md","docs/docs/getting-started/resources.md","docs/docs/getting-started/usage.md","docs/docs/index.md","docs/docs/terms/index.md","docs/docs/terms/license.md","docs/generate_api.py","docs/mkdocs.yml","docs/overrides/main.html","docs/templates/markdown.mako","docs/update_api_nav.py","examples/BitcoinDMAC.ipynb","examples/MACDVolume.ipynb","examples/PairsTrading.ipynb","examples/PortfolioOptimization.ipynb","examples/PortingBTStrategy.ipynb","examples/StopSignals.ipynb","examples/TelegramSignals.ipynb","examples/TradingSessions.ipynb","examples/WalkForwardOptimization.ipynb","examples/dmac_heatmap.gif","examples/requirements-backtrader.txt","mypy.ini","pyproject.toml","rust/Cargo.lock","rust/Cargo.toml","rust/README.md","rust/pyproject.toml","rust/rustfmt.toml","rust/src/generic.rs","rust/src/indicators.rs","rust/src/labels.rs","rust/src/lib.rs","rust/src/portfolio.rs","rust/src/records.rs","rust/src/returns.rs","rust/src/signals.rs","setup.py","tests/__init__.py","tests/conftest.py","tests/notebooks/base.ipynb","tests/notebooks/generic.ipynb","tests/notebooks/indicators.ipynb","tests/notebooks/labels.ipynb","tests/notebooks/ohlcv.ipynb","tests/notebooks/plotting.ipynb","tests/notebooks/portfolio.ipynb","tests/notebooks/records.ipynb","tests/notebooks/returns.ipynb","tests/notebooks/shortcash.ipynb","tests/notebooks/signals.ipynb","tests/notebooks/utils.ipynb","tests/test_base.py","tests/test_data.py","tests/test_engine.py","tests/test_generic.py","tests/test_indicators.py","tests/test_labels.py","tests/test_plotting.py","tests/test_portfolio.py","tests/test_records.py","tests/test_returns.py","tests/test_settings.py","tests/test_signals.py","tests/test_utils.py","tests/utils.py","vectorbt/__init__.py","vectorbt/_engine.py","vectorbt/_settings.py","vectorbt/_typing.py","vectorbt/_version.py","vectorbt/base/__init__.py","vectorbt/base/accessors.py","vectorbt/base/array_wrapper.py","vectorbt/base/column_grouper.py","vectorbt/base/combine_fns.py","vectorbt/base/index_fns.py","vectorbt/base/indexing.py","vectorbt/base/reshape_fns.py","vectorbt/data/__init__.py","vectorbt/data/base.py","vectorbt/data/custom.py","vectorbt/data/updater.py","vectorbt/generic/__init__.py","vectorbt/generic/accessors.py","vectorbt/generic/decorators.py","vectorbt/generic/dispatch.py","vectorbt/generic/drawdowns.py","vectorbt/generic/enums.py","vectorbt/generic/nb.py","vectorbt/generic/plots_builder.py","vectorbt/generic/plotting.py","vectorbt/generic/ranges.py","vectorbt/generic/splitters.py","vectorbt/generic/stats_builder.py","vectorbt/indicators/__init__.py","vectorbt/indicators/basic.py","vectorbt/indicators/configs.py","vectorbt/indicators/dispatch.py","vectorbt/indicators/factory.py","vectorbt/indicators/nb.py","vectorbt/labels/__init__.py","vectorbt/labels/dispatch.py","vectorbt/labels/enums.py","vectorbt/labels/generators.py","vectorbt/labels/nb.py","vectorbt/messaging/__init__.py","vectorbt/messaging/telegram.py","vectorbt/ohlcv_accessors.py","vectorbt/portfolio/__init__.py","vectorbt/portfolio/base.py","vectorbt/portfolio/decorators.py","vectorbt/portfolio/dispatch.py","vectorbt/portfolio/enums.py","vectorbt/portfolio/logs.py","vectorbt/portfolio/nb.py","vectorbt/portfolio/orders.py","vectorbt/portfolio/trades.py","vectorbt/px_accessors.py","vectorbt/records/__init__.py","vectorbt/records/base.py","vectorbt/records/col_mapper.py","vectorbt/records/decorators.py","vectorbt/records/dispatch.py","vectorbt/records/mapped_array.py","vectorbt/records/nb.py","vectorbt/returns/__init__.py","vectorbt/returns/accessors.py","vectorbt/returns/dispatch.py","vectorbt/returns/metrics.py","vectorbt/returns/nb.py","vectorbt/returns/qs_adapter.py","vectorbt/root_accessors.py","vectorbt/signals/__init__.py","vectorbt/signals/accessors.py","vectorbt/signals/dispatch.py","vectorbt/signals/enums.py","vectorbt/signals/factory.py","vectorbt/signals/generators.py","vectorbt/signals/nb.py","vectorbt/templates/dark.json","vectorbt/templates/light.json","vectorbt/templates/seaborn.json","vectorbt/utils/__init__.py","vectorbt/utils/array_.py","vectorbt/utils/attr_.py","vectorbt/utils/checks.py","vectorbt/utils/colors.py","vectorbt/utils/config.py","vectorbt/utils/datetime_.py","vectorbt/utils/decorators.py","vectorbt/utils/docs.py","vectorbt/utils/enum_.py","vectorbt/utils/figure.py","vectorbt/utils/image_.py","vectorbt/utils/mapping.py","vectorbt/utils/math_.py","vectorbt/utils/module_.py","vectorbt/utils/params.py","vectorbt/utils/random_.py","vectorbt/utils/requests_.py","vectorbt/utils/schedule_.py","vectorbt/utils/tags.py","vectorbt/utils/template.py"],"storefront":"/r/polakowo","claimed":false,"request_supported":{"post":"https://gitbuyer.com/r/polakowo/vectorbt/request-supported","requests":0},"note":"indexed from public GitHub; nothing is for sale on this page. Clone it from GitHub. Paid listings live at /search."}