Notebooks/Backtesting with vectorbt
Backtesting·Libraries·Intermediate

Backtesting with vectorbt

Use the vectorbt library for high-performance portfolio backtesting with built-in metrics, portfolio simulation, and visualization.

vectorbtportfolioperformance

Backtesting Libraries — vectorbt


1. Dependency Installation

[1]
!pip install pandas numpy vectorbt plotly
Requirement already satisfied: pandas in /usr/local/lib/python3.12/dist-packages (2.2.2)
Requirement already satisfied: numpy in /usr/local/lib/python3.12/dist-packages (2.0.2)
Collecting vectorbt
  Downloading vectorbt-1.0.0-py3-none-any.whl.metadata (14 kB)
Requirement already satisfied: plotly in /usr/local/lib/python3.12/dist-packages (5.24.1)
Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.12/dist-packages (from pandas) (2.9.0.post0)
Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.12/dist-packages (from pandas) (2025.2)
Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.12/dist-packages (from pandas) (2026.1)
Requirement already satisfied: scipy in /usr/local/lib/python3.12/dist-packages (from vectorbt) (1.16.3)
Requirement already satisfied: matplotlib in /usr/local/lib/python3.12/dist-packages (from vectorbt) (3.10.0)
Requirement already satisfied: ipywidgets>=7.0.0 in /usr/local/lib/python3.12/dist-packages (from vectorbt) (7.7.1)
Requirement already satisfied: anywidget in /usr/local/lib/python3.12/dist-packages (from vectorbt) (0.9.21)
Requirement already satisfied: numba>=0.60 in /usr/local/lib/python3.12/dist-packages (from vectorbt) (0.60.0)
Requirement already satisfied: dill in /usr/local/lib/python3.12/dist-packages (from vectorbt) (0.3.8)
Requirement already satisfied: tqdm in /usr/local/lib/python3.12/dist-packages (from vectorbt) (4.67.3)
Collecting dateparser (from vectorbt)
  Downloading dateparser-1.4.0-py3-none-any.whl.metadata (31 kB)
Requirement already satisfied: imageio in /usr/local/lib/python3.12/dist-packages (from vectorbt) (2.37.3)
Requirement already satisfied: scikit-learn in /usr/local/lib/python3.12/dist-packages (from vectorbt) (1.6.1)
Collecting schedule (from vectorbt)
  Downloading schedule-1.2.2-py3-none-any.whl.metadata (3.8 kB)
Requirement already satisfied: requests in /usr/local/lib/python3.12/dist-packages (from vectorbt) (2.32.4)
Collecting mypy_extensions (from vectorbt)
  Downloading mypy_extensions-1.1.0-py3-none-any.whl.metadata (1.1 kB)
Requirement already satisfied: tenacity>=6.2.0 in /usr/local/lib/python3.12/dist-packages (from plotly) (9.1.4)
Requirement already satisfied: packaging in /usr/local/lib/python3.12/dist-packages (from plotly) (26.1)
Requirement already satisfied: ipykernel>=4.5.1 in /usr/local/lib/python3.12/dist-packages (from ipywidgets>=7.0.0->vectorbt) (6.17.1)
Requirement already satisfied: ipython-genutils~=0.2.0 in /usr/local/lib/python3.12/dist-packages (from ipywidgets>=7.0.0->vectorbt) (0.2.0)
Requirement already satisfied: traitlets>=4.3.1 in /usr/local/lib/python3.12/dist-packages (from ipywidgets>=7.0.0->vectorbt) (5.7.1)
Requirement already satisfied: widgetsnbextension~=3.6.0 in /usr/local/lib/python3.12/dist-packages (from ipywidgets>=7.0.0->vectorbt) (3.6.10)
Requirement already satisfied: ipython>=4.0.0 in /usr/local/lib/python3.12/dist-packages (from ipywidgets>=7.0.0->vectorbt) (7.34.0)
Requirement already satisfied: jupyterlab-widgets>=1.0.0 in /usr/local/lib/python3.12/dist-packages (from ipywidgets>=7.0.0->vectorbt) (3.0.16)
Requirement already satisfied: llvmlite<0.44,>=0.43.0dev0 in /usr/local/lib/python3.12/dist-packages (from numba>=0.60->vectorbt) (0.43.0)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.12/dist-packages (from python-dateutil>=2.8.2->pandas) (1.17.0)
Requirement already satisfied: psygnal>=0.8.1 in /usr/local/lib/python3.12/dist-packages (from anywidget->vectorbt) (0.15.1)
Requirement already satisfied: typing-extensions>=4.2.0 in /usr/local/lib/python3.12/dist-packages (from anywidget->vectorbt) (4.15.0)
Requirement already satisfied: regex>=2024.9.11 in /usr/local/lib/python3.12/dist-packages (from dateparser->vectorbt) (2025.11.3)
Requirement already satisfied: tzlocal>=0.2 in /usr/local/lib/python3.12/dist-packages (from dateparser->vectorbt) (5.3.1)
Requirement already satisfied: pillow>=8.3.2 in /usr/local/lib/python3.12/dist-packages (from imageio->vectorbt) (11.3.0)
Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.12/dist-packages (from matplotlib->vectorbt) (1.3.3)
Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.12/dist-packages (from matplotlib->vectorbt) (0.12.1)
Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.12/dist-packages (from matplotlib->vectorbt) (4.62.1)
Requirement already satisfied: kiwisolver>=1.3.1 in /usr/local/lib/python3.12/dist-packages (from matplotlib->vectorbt) (1.5.0)
Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.12/dist-packages (from matplotlib->vectorbt) (3.3.2)
Requirement already satisfied: charset_normalizer<4,>=2 in /usr/local/lib/python3.12/dist-packages (from requests->vectorbt) (3.4.7)
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.12/dist-packages (from requests->vectorbt) (3.13)
Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.12/dist-packages (from requests->vectorbt) (2.5.0)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.12/dist-packages (from requests->vectorbt) (2026.4.22)
Requirement already satisfied: joblib>=1.2.0 in /usr/local/lib/python3.12/dist-packages (from scikit-learn->vectorbt) (1.5.3)
Requirement already satisfied: threadpoolctl>=3.1.0 in /usr/local/lib/python3.12/dist-packages (from scikit-learn->vectorbt) (3.6.0)
Requirement already satisfied: debugpy>=1.0 in /usr/local/lib/python3.12/dist-packages (from ipykernel>=4.5.1->ipywidgets>=7.0.0->vectorbt) (1.8.15)
Requirement already satisfied: jupyter-client>=6.1.12 in /usr/local/lib/python3.12/dist-packages (from ipykernel>=4.5.1->ipywidgets>=7.0.0->vectorbt) (7.4.9)
Requirement already satisfied: matplotlib-inline>=0.1 in /usr/local/lib/python3.12/dist-packages (from ipykernel>=4.5.1->ipywidgets>=7.0.0->vectorbt) (0.2.1)
Requirement already satisfied: nest-asyncio in /usr/local/lib/python3.12/dist-packages (from ipykernel>=4.5.1->ipywidgets>=7.0.0->vectorbt) (1.6.0)
Requirement already satisfied: psutil in /usr/local/lib/python3.12/dist-packages (from ipykernel>=4.5.1->ipywidgets>=7.0.0->vectorbt) (5.9.5)
Requirement already satisfied: pyzmq>=17 in /usr/local/lib/python3.12/dist-packages (from ipykernel>=4.5.1->ipywidgets>=7.0.0->vectorbt) (26.2.1)
Requirement already satisfied: tornado>=6.1 in /usr/local/lib/python3.12/dist-packages (from ipykernel>=4.5.1->ipywidgets>=7.0.0->vectorbt) (6.5.1)
Requirement already satisfied: setuptools>=18.5 in /usr/local/lib/python3.12/dist-packages (from ipython>=4.0.0->ipywidgets>=7.0.0->vectorbt) (75.2.0)
Collecting jedi>=0.16 (from ipython>=4.0.0->ipywidgets>=7.0.0->vectorbt)
  Downloading jedi-0.20.0-py2.py3-none-any.whl.metadata (23 kB)
Requirement already satisfied: decorator in /usr/local/lib/python3.12/dist-packages (from ipython>=4.0.0->ipywidgets>=7.0.0->vectorbt) (4.4.2)
Requirement already satisfied: pickleshare in /usr/local/lib/python3.12/dist-packages (from ipython>=4.0.0->ipywidgets>=7.0.0->vectorbt) (0.7.5)
Requirement already satisfied: prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0 in /usr/local/lib/python3.12/dist-packages (from ipython>=4.0.0->ipywidgets>=7.0.0->vectorbt) (3.0.52)
Requirement already satisfied: pygments in /usr/local/lib/python3.12/dist-packages (from ipython>=4.0.0->ipywidgets>=7.0.0->vectorbt) (2.20.0)
Requirement already satisfied: backcall in /usr/local/lib/python3.12/dist-packages (from ipython>=4.0.0->ipywidgets>=7.0.0->vectorbt) (0.2.0)
Requirement already satisfied: pexpect>4.3 in /usr/local/lib/python3.12/dist-packages (from ipython>=4.0.0->ipywidgets>=7.0.0->vectorbt) (4.9.0)
Requirement already satisfied: notebook>=4.4.1 in /usr/local/lib/python3.12/dist-packages (from widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (6.5.7)
Requirement already satisfied: parso<0.9.0,>=0.8.6 in /usr/local/lib/python3.12/dist-packages (from jedi>=0.16->ipython>=4.0.0->ipywidgets>=7.0.0->vectorbt) (0.8.6)
Requirement already satisfied: entrypoints in /usr/local/lib/python3.12/dist-packages (from jupyter-client>=6.1.12->ipykernel>=4.5.1->ipywidgets>=7.0.0->vectorbt) (0.4)
Requirement already satisfied: jupyter-core>=4.9.2 in /usr/local/lib/python3.12/dist-packages (from jupyter-client>=6.1.12->ipykernel>=4.5.1->ipywidgets>=7.0.0->vectorbt) (5.9.1)
Requirement already satisfied: jinja2 in /usr/local/lib/python3.12/dist-packages (from notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (3.1.6)
Requirement already satisfied: argon2-cffi in /usr/local/lib/python3.12/dist-packages (from notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (25.1.0)
Requirement already satisfied: nbformat in /usr/local/lib/python3.12/dist-packages (from notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (5.10.4)
Requirement already satisfied: nbconvert>=5 in /usr/local/lib/python3.12/dist-packages (from notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (7.17.1)
Requirement already satisfied: Send2Trash>=1.8.0 in /usr/local/lib/python3.12/dist-packages (from notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (2.1.0)
Requirement already satisfied: terminado>=0.8.3 in /usr/local/lib/python3.12/dist-packages (from notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (0.18.1)
Requirement already satisfied: prometheus-client in /usr/local/lib/python3.12/dist-packages (from notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (0.25.0)
Requirement already satisfied: nbclassic>=0.4.7 in /usr/local/lib/python3.12/dist-packages (from notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (1.3.3)
Requirement already satisfied: ptyprocess>=0.5 in /usr/local/lib/python3.12/dist-packages (from pexpect>4.3->ipython>=4.0.0->ipywidgets>=7.0.0->vectorbt) (0.7.0)
Requirement already satisfied: wcwidth in /usr/local/lib/python3.12/dist-packages (from prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0->ipython>=4.0.0->ipywidgets>=7.0.0->vectorbt) (0.6.0)
Requirement already satisfied: platformdirs>=2.5 in /usr/local/lib/python3.12/dist-packages (from jupyter-core>=4.9.2->jupyter-client>=6.1.12->ipykernel>=4.5.1->ipywidgets>=7.0.0->vectorbt) (4.9.6)
Requirement already satisfied: notebook-shim>=0.2.3 in /usr/local/lib/python3.12/dist-packages (from nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (0.2.4)
Requirement already satisfied: beautifulsoup4 in /usr/local/lib/python3.12/dist-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (4.13.5)
Requirement already satisfied: bleach!=5.0.0 in /usr/local/lib/python3.12/dist-packages (from bleach[css]!=5.0.0->nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (6.3.0)
Requirement already satisfied: defusedxml in /usr/local/lib/python3.12/dist-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (0.7.1)
Requirement already satisfied: jupyterlab-pygments in /usr/local/lib/python3.12/dist-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (0.3.0)
Requirement already satisfied: markupsafe>=2.0 in /usr/local/lib/python3.12/dist-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (3.0.3)
Requirement already satisfied: mistune<4,>=2.0.3 in /usr/local/lib/python3.12/dist-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (3.2.0)
Requirement already satisfied: nbclient>=0.5.0 in /usr/local/lib/python3.12/dist-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (0.10.4)
Requirement already satisfied: pandocfilters>=1.4.1 in /usr/local/lib/python3.12/dist-packages (from nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (1.5.1)
Requirement already satisfied: fastjsonschema>=2.15 in /usr/local/lib/python3.12/dist-packages (from nbformat->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (2.21.2)
Requirement already satisfied: jsonschema>=2.6 in /usr/local/lib/python3.12/dist-packages (from nbformat->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (4.26.0)
Requirement already satisfied: argon2-cffi-bindings in /usr/local/lib/python3.12/dist-packages (from argon2-cffi->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (25.1.0)
Requirement already satisfied: webencodings in /usr/local/lib/python3.12/dist-packages (from bleach!=5.0.0->bleach[css]!=5.0.0->nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (0.5.1)
Requirement already satisfied: tinycss2<1.5,>=1.1.0 in /usr/local/lib/python3.12/dist-packages (from bleach[css]!=5.0.0->nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (1.4.0)
Requirement already satisfied: attrs>=22.2.0 in /usr/local/lib/python3.12/dist-packages (from jsonschema>=2.6->nbformat->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (26.1.0)
Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /usr/local/lib/python3.12/dist-packages (from jsonschema>=2.6->nbformat->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (2025.9.1)
Requirement already satisfied: referencing>=0.28.4 in /usr/local/lib/python3.12/dist-packages (from jsonschema>=2.6->nbformat->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (0.37.0)
Requirement already satisfied: rpds-py>=0.25.0 in /usr/local/lib/python3.12/dist-packages (from jsonschema>=2.6->nbformat->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (0.30.0)
Requirement already satisfied: jupyter-server<3,>=1.8 in /usr/local/lib/python3.12/dist-packages (from notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (2.14.0)
Requirement already satisfied: cffi>=1.0.1 in /usr/local/lib/python3.12/dist-packages (from argon2-cffi-bindings->argon2-cffi->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (2.0.0)
Requirement already satisfied: soupsieve>1.2 in /usr/local/lib/python3.12/dist-packages (from beautifulsoup4->nbconvert>=5->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (2.8.3)
Requirement already satisfied: pycparser in /usr/local/lib/python3.12/dist-packages (from cffi>=1.0.1->argon2-cffi-bindings->argon2-cffi->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (3.0)
Requirement already satisfied: anyio>=3.1.0 in /usr/local/lib/python3.12/dist-packages (from jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (4.13.0)
Requirement already satisfied: jupyter-events>=0.9.0 in /usr/local/lib/python3.12/dist-packages (from jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (0.12.1)
Requirement already satisfied: jupyter-server-terminals>=0.4.4 in /usr/local/lib/python3.12/dist-packages (from jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (0.5.4)
Requirement already satisfied: overrides>=5.0 in /usr/local/lib/python3.12/dist-packages (from jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (7.7.0)
Requirement already satisfied: websocket-client>=1.7 in /usr/local/lib/python3.12/dist-packages (from jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (1.9.0)
Requirement already satisfied: python-json-logger>=2.0.4 in /usr/local/lib/python3.12/dist-packages (from jupyter-events>=0.9.0->jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (4.1.0)
Requirement already satisfied: pyyaml>=5.3 in /usr/local/lib/python3.12/dist-packages (from jupyter-events>=0.9.0->jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (6.0.3)
Requirement already satisfied: rfc3339-validator in /usr/local/lib/python3.12/dist-packages (from jupyter-events>=0.9.0->jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (0.1.4)
Requirement already satisfied: rfc3986-validator>=0.1.1 in /usr/local/lib/python3.12/dist-packages (from jupyter-events>=0.9.0->jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (0.1.1)
Requirement already satisfied: fqdn in /usr/local/lib/python3.12/dist-packages (from jsonschema[format-nongpl]>=4.18.0->jupyter-events>=0.9.0->jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (1.5.1)
Requirement already satisfied: isoduration in /usr/local/lib/python3.12/dist-packages (from jsonschema[format-nongpl]>=4.18.0->jupyter-events>=0.9.0->jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (20.11.0)
Requirement already satisfied: jsonpointer>1.13 in /usr/local/lib/python3.12/dist-packages (from jsonschema[format-nongpl]>=4.18.0->jupyter-events>=0.9.0->jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (3.1.1)
Requirement already satisfied: rfc3987-syntax>=1.1.0 in /usr/local/lib/python3.12/dist-packages (from jsonschema[format-nongpl]>=4.18.0->jupyter-events>=0.9.0->jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (1.1.0)
Requirement already satisfied: uri-template in /usr/local/lib/python3.12/dist-packages (from jsonschema[format-nongpl]>=4.18.0->jupyter-events>=0.9.0->jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (1.3.0)
Requirement already satisfied: webcolors>=24.6.0 in /usr/local/lib/python3.12/dist-packages (from jsonschema[format-nongpl]>=4.18.0->jupyter-events>=0.9.0->jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (25.10.0)
Requirement already satisfied: lark>=1.2.2 in /usr/local/lib/python3.12/dist-packages (from rfc3987-syntax>=1.1.0->jsonschema[format-nongpl]>=4.18.0->jupyter-events>=0.9.0->jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (1.3.1)
Requirement already satisfied: arrow>=0.15.0 in /usr/local/lib/python3.12/dist-packages (from isoduration->jsonschema[format-nongpl]>=4.18.0->jupyter-events>=0.9.0->jupyter-server<3,>=1.8->notebook-shim>=0.2.3->nbclassic>=0.4.7->notebook>=4.4.1->widgetsnbextension~=3.6.0->ipywidgets>=7.0.0->vectorbt) (1.4.0)
Downloading vectorbt-1.0.0-py3-none-any.whl (451 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 451.7/451.7 kB 7.4 MB/s eta 0:00:00
[?25hDownloading dateparser-1.4.0-py3-none-any.whl (300 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 300.4/300.4 kB 8.9 MB/s eta 0:00:00
[?25hDownloading mypy_extensions-1.1.0-py3-none-any.whl (5.0 kB)
Downloading schedule-1.2.2-py3-none-any.whl (12 kB)
Downloading jedi-0.20.0-py2.py3-none-any.whl (4.9 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.9/4.9 MB 31.7 MB/s eta 0:00:00
[?25hInstalling collected packages: schedule, mypy_extensions, jedi, dateparser, vectorbt
Successfully installed dateparser-1.4.0 jedi-0.20.0 mypy_extensions-1.1.0 schedule-1.2.2 vectorbt-1.0.0

2. Library Imports

[2]
import warnings
warnings.filterwarnings("ignore")

import pandas as pd
import numpy as np
import vectorbt as vbt
import plotly.graph_objects as go
from plotly.subplots import make_subplots

3. What Is vectorbt?

vectorbt is a Python library for high-performance portfolio backtesting built on top of numpy and pandas. It is designed to evaluate thousands of parameter combinations simultaneously using vectorized array operations, making it the standard tool for parameter optimization and strategy screening.

Key features:

| Feature | Description | |---| | Vectorized computation | Entire backtest runs as array operations — no Python loops | | Parameter sweeps | Test all combinations of parameters in one call | | Built-in indicators | SMA, EMA, RSI, MACD, Bollinger Bands, and 100+ others | | Portfolio simulation | Fees, slippage, position sizing, and cash management in one API | | Performance analytics | Sharpe, Sortino, Calmar, drawdown, trade statistics built in | | Interactive plotting | Plotly-based charts for equity curves, trade markers, heatmaps |

When to use vectorbt vs event-driven:

  • vectorbt: Parameter optimization, signal screening, fast iteration during research.
  • Event-driven (Notebook 67): Final performance validation, realistic execution modeling, live system development.

4. Data Generation

[3]
def generate_data(periods: int) -> pd.DataFrame:
    start_date     = pd.to_datetime("2024-01-01 00:00:00+00:00")
    datetime_index = pd.date_range(start_date, periods=periods, freq="1min", tz="UTC")
    price_data = []; last_close = 42000
    volatility_scale = 0.005; wick_scale = 0.002

    for _ in range(periods):
        open_price  = last_close + np.random.normal(0, last_close * volatility_scale * 0.1)
        close_price = open_price + np.random.normal(0, last_close * volatility_scale)
        body_high   = max(open_price, close_price)
        body_low    = min(open_price, close_price)
        high_price  = max(body_high + abs(np.random.normal(0, last_close * wick_scale)),
                          open_price, close_price)
        low_price   = min(body_low  - abs(np.random.normal(0, last_close * wick_scale)),
                          open_price, close_price)
        if high_price < low_price:
            high_price, low_price = low_price, high_price
        price_data.append({
            "open":  max(1, int(open_price)),
            "high":  max(1, int(high_price)),
            "low":   max(1, int(low_price)),
            "close": max(1, int(close_price)),
        })
        last_close = close_price

    df = pd.DataFrame(price_data, index=datetime_index)
    df.index.name = "datetime"
    df["volume"]   = np.random.uniform(100.0, 500.0, periods)
    df["datetime"] = df.index.to_series()
    return df.reset_index(drop=True)

df = generate_data(500)

# Convert to indexed Series for vectorbt compatibility
close_series = pd.Series(
    df["close"].values,
    index=pd.DatetimeIndex(df["datetime"]),
    name="close",
)

display(df.head())
print(f"Series length: {len(close_series)}")
open high low close volume datetime
0 41983 42045 41972 41981 214.866516 2024-01-01 00:00:00+00:00
1 41986 42535 41820 42442 122.914521 2024-01-01 00:01:00+00:00
2 42425 43150 42363 43082 422.954606 2024-01-01 00:02:00+00:00
3 43097 43157 43002 43115 163.932242 2024-01-01 00:03:00+00:00
4 43097 43209 42713 42927 329.700926 2024-01-01 00:04:00+00:00
Series length: 500

5. Single-Parameter Backtest

[4]
# --- Compute moving averages using vectorbt's built-in indicator engine ---
fast_ma = vbt.MA.run(close_series, window=10)
slow_ma = vbt.MA.run(close_series, window=30)

# --- Generate entry and exit signals ---
entries = fast_ma.ma_crossed_above(slow_ma)   # Fast MA crosses above slow MA
exits   = fast_ma.ma_crossed_below(slow_ma)   # Fast MA crosses below slow MA

# --- Build and run portfolio ---
portfolio = vbt.Portfolio.from_signals(
    close_series,
    entries,
    exits,
    init_cash   = 10_000,
    fees        = 0.001,        # 0.1% per trade (round-trip = 0.2%)
    freq        = "1min",
)

print("--- vectorbt Portfolio Statistics ---")
print(portfolio.stats())
--- vectorbt Portfolio Statistics ---
Start                         2024-01-01 00:00:00+00:00
End                           2024-01-01 08:19:00+00:00
Period                                  0 days 08:20:00
Start Value                                     10000.0
End Value                                    9407.42885
Total Return [%]                              -5.925711
Benchmark Return [%]                           2.012815
Max Gross Exposure [%]                            100.0
Total Fees Paid                              200.497049
Max Drawdown [%]                              13.034522
Max Drawdown Duration                   0 days 04:18:00
Total Trades                                         10
Total Closed Trades                                  10
Total Open Trades                                     0
Open Trade PnL                                      0.0
Win Rate [%]                                       20.0
Best Trade [%]                                 4.164551
Worst Trade [%]                                -2.68185
Avg Winning Trade [%]                          3.832015
Avg Losing Trade [%]                          -1.687851
Avg Winning Trade Duration              0 days 01:07:30
Avg Losing Trade Duration               0 days 00:13:00
Profit Factor                                  0.565981
Expectancy                                   -59.257115
Sharpe Ratio                                  -23.85127
Calmar Ratio                                  -7.671935
Omega Ratio                                    0.888054
Sortino Ratio                                -32.249531
dtype: object

Explanation:

  • vbt.MA.run(close_series, window=10): Computes the moving average using vectorbt's indicator pipeline. The result is a vectorbt indicator object that supports crossover detection directly.
  • ma_crossed_above(slow_ma): Returns a boolean Series that is True only on the exact candle where the fast MA crosses above the slow MA — equivalent to (fast > slow) & (fast.shift(1) <= slow.shift(1)).
  • vbt.Portfolio.from_signals: The core portfolio simulator. It processes the entry and exit boolean arrays, manages cash, applies fees, and tracks position state — all in a single vectorized pass. The freq parameter is used for annualizing performance metrics.
  • portfolio.stats(): Returns a comprehensive dictionary of performance metrics including total return, Sharpe ratio, max drawdown, win rate, and trade count.

6. Parameter Optimization

[5]
# --- Multi-parameter sweep: test all combinations of fast and slow windows ---
fast_windows = [5, 10, 15, 20]
slow_windows = [20, 30, 40, 50]

fast_ma_multi = vbt.MA.run(close_series, window=fast_windows, short_name="fast")
slow_ma_multi = vbt.MA.run(close_series, window=slow_windows, short_name="slow")

entries_multi = fast_ma_multi.ma_crossed_above(slow_ma_multi)
exits_multi   = fast_ma_multi.ma_crossed_below(slow_ma_multi)

portfolio_multi = vbt.Portfolio.from_signals(
    close_series,
    entries_multi,
    exits_multi,
    init_cash = 10_000,
    fees      = 0.001,
    freq      = "1min",
)

# Extract total return for each parameter combination
returns_matrix = portfolio_multi.total_return()
print("--- Total Return Matrix (Fast Window × Slow Window) ---")
display(returns_matrix.unstack())
--- Total Return Matrix (Fast Window × Slow Window) ---
slow_window 20 30 40 50
fast_window
5 -0.139453 NaN NaN NaN
10 NaN -0.059257 NaN NaN
15 NaN NaN -0.055753 NaN
20 NaN NaN NaN -0.048005

Explanation: vectorbt evaluates all 16 parameter combinations (4 fast × 4 slow) simultaneously in a single function call — no outer loop is required. The result is a matrix where each cell contains the total return for that fast/slow window pair. This capability is what makes vectorbt the standard tool for strategy parameter optimization — equivalent analysis in a loop-based framework would require 16 separate backtest runs.


7. Visualization

[7]
buy_signals_mask  = entries[entries].index
sell_signals_mask = exits[exits].index

fig = make_subplots(
    rows=2, cols=1, shared_xaxes=True,
    subplot_titles=[
        "Price + MA Crossover + Entry/Exit Signals",
        "vectorbt Equity Curve",
    ],
    row_heights=[0.55, 0.45],
)

fig.add_trace(go.Candlestick(
    x=df["datetime"],
    open=df["open"], high=df["high"],
    low=df["low"],   close=df["close"],
    name="Price"), row=1, col=1)

fig.add_trace(go.Scatter(
    x=close_series.index, y=fast_ma.ma.values,
    mode="lines", name="Fast MA (10)",
    line=dict(color="blue", width=1)), row=1, col=1)

fig.add_trace(go.Scatter(
    x=close_series.index, y=slow_ma.ma.values,
    mode="lines", name="Slow MA (30)",
    line=dict(color="orange", width=1)), row=1, col=1)

buy_prices  = close_series.loc[buy_signals_mask]
sell_prices = close_series.loc[sell_signals_mask]

fig.add_trace(go.Scatter(
    x=buy_prices.index,
    y=buy_prices.values  * 0.999,
    mode="markers",
    marker=dict(symbol="triangle-up",   size=10, color="green"),
    name="Buy Signal"), row=1, col=1)

fig.add_trace(go.Scatter(
    x=sell_prices.index,
    y=sell_prices.values * 1.001,
    mode="markers",
    marker=dict(symbol="triangle-down", size=10, color="red"),
    name="Sell Signal"), row=1, col=1)

equity_values = portfolio.value()
fig.add_trace(go.Scatter(
    x=equity_values.index, y=equity_values.values,
    mode="lines", name="Portfolio Value ($)",
    line=dict(color="green", width=2)), row=2, col=1)

fig.update_layout(
    title_text="vectorbt Backtest — MA Crossover Strategy",
    xaxis_rangeslider_visible=False,
    height=800,
    yaxis=dict(autorange=True),
    xaxis2_title="Datetime",
    yaxis_title="Price",
    yaxis2_title="Portfolio Value ($)",
)
fig.show()
[ ]

Task

I will update the notebook to improve its formality, clarity, and consistency. Specifically, I will:

  • Refine the introductory markdown cells (e5741ce3, eefdc1e3) for a more formal and technical presentation.
  • Add comments to the dependency installation code (6a30bce5) to explain its purpose.
  • Modify the library imports markdown (5ffcb3ab) and add detailed comments to the import code (4554082d) for documentation purposes.
  • Rewrite the 'What Is vectorbt?' markdown section (b6da932e) to be concise, technically accurate, and formal.
  • Enhance the 'Data Generation' markdown introduction (bf923033) and add technical comments to the generate_data function and close_series conversion within the code cell (4c4965df).
  • Improve the 'Single-Parameter Backtest' markdown introduction (9a218c0b), add technical comments to the backtest code (c03c38b8), and rewrite its 'Explanation' markdown (598b7240).
  • Refine the 'Parameter Optimization' markdown introduction (2a617563), add technical comments to the multi-parameter sweep code (2426f084), and rewrite its 'Explanation' markdown (e6440eba).
  • Enhance the 'Visualization' markdown introduction (00861abe) and add comments to the plotting code (da05a445) to explain each component.

I will confirm that all changes adhere to the specified rules upon completion.