vectorbt 0.28.2__tar.gz → 0.28.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {vectorbt-0.28.2 → vectorbt-0.28.4}/LICENSE.md +1 -1
- {vectorbt-0.28.2/vectorbt.egg-info → vectorbt-0.28.4}/PKG-INFO +116 -120
- vectorbt-0.28.4/README.md +246 -0
- vectorbt-0.28.4/pyproject.toml +90 -0
- vectorbt-0.28.4/setup.py +3 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/tests/test_generic.py +9 -16
- {vectorbt-0.28.2 → vectorbt-0.28.4}/tests/test_indicators.py +16 -2
- {vectorbt-0.28.2 → vectorbt-0.28.4}/tests/test_records.py +0 -14
- {vectorbt-0.28.2 → vectorbt-0.28.4}/tests/test_utils.py +20 -1
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/_version.py +1 -1
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/base/array_wrapper.py +2 -2
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/base/indexing.py +19 -5
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/generic/accessors.py +5 -10
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/records/base.py +1 -1
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/records/mapped_array.py +5 -10
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/checks.py +71 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/datetime_.py +1 -2
- {vectorbt-0.28.2 → vectorbt-0.28.4/vectorbt.egg-info}/PKG-INFO +116 -120
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt.egg-info/SOURCES.txt +1 -4
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt.egg-info/requires.txt +5 -14
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt.egg-info/top_level.txt +0 -1
- vectorbt-0.28.2/MANIFEST.in +0 -1
- vectorbt-0.28.2/README.md +0 -232
- vectorbt-0.28.2/setup.py +0 -94
- vectorbt-0.28.2/tests/__init__.py +0 -0
- vectorbt-0.28.2/tests/utils.py +0 -21
- vectorbt-0.28.2/vectorbt/templates/.ipynb_checkpoints/dark-checkpoint.json +0 -813
- {vectorbt-0.28.2 → vectorbt-0.28.4}/setup.cfg +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/tests/test_base.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/tests/test_data.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/tests/test_labels.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/tests/test_portfolio.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/tests/test_returns.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/tests/test_settings.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/tests/test_signals.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/__init__.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/_settings.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/_typing.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/base/__init__.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/base/accessors.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/base/column_grouper.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/base/combine_fns.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/base/index_fns.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/base/reshape_fns.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/data/__init__.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/data/base.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/data/custom.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/data/updater.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/generic/__init__.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/generic/decorators.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/generic/drawdowns.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/generic/enums.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/generic/nb.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/generic/plots_builder.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/generic/plotting.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/generic/ranges.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/generic/splitters.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/generic/stats_builder.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/indicators/__init__.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/indicators/basic.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/indicators/configs.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/indicators/factory.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/indicators/nb.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/labels/__init__.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/labels/enums.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/labels/generators.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/labels/nb.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/messaging/__init__.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/messaging/telegram.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/ohlcv_accessors.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/portfolio/__init__.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/portfolio/base.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/portfolio/decorators.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/portfolio/enums.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/portfolio/logs.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/portfolio/nb.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/portfolio/orders.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/portfolio/trades.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/px_accessors.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/records/__init__.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/records/col_mapper.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/records/decorators.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/records/nb.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/returns/__init__.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/returns/accessors.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/returns/metrics.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/returns/nb.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/returns/qs_adapter.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/root_accessors.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/signals/__init__.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/signals/accessors.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/signals/enums.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/signals/factory.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/signals/generators.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/signals/nb.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/templates/dark.json +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/templates/light.json +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/templates/seaborn.json +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/__init__.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/array_.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/attr_.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/colors.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/config.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/decorators.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/docs.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/enum_.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/figure.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/image_.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/mapping.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/math_.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/module_.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/params.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/random_.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/requests_.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/schedule_.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/tags.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt/utils/template.py +0 -0
- {vectorbt-0.28.2 → vectorbt-0.28.4}/vectorbt.egg-info/dependency_links.txt +0 -0
|
@@ -200,7 +200,7 @@ Licensor: Oleg Polakow
|
|
|
200
200
|
same "printed page" as the copyright notice for easier
|
|
201
201
|
identification within third-party archives.
|
|
202
202
|
|
|
203
|
-
Copyright
|
|
203
|
+
Copyright 2026 Oleg Polakow
|
|
204
204
|
|
|
205
205
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
206
206
|
you may not use this file except in compliance with the License.
|
|
@@ -1,39 +1,32 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vectorbt
|
|
3
|
-
Version: 0.28.
|
|
3
|
+
Version: 0.28.4
|
|
4
4
|
Summary: Python library for backtesting and analyzing trading strategies at scale
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Author-email: olegpolakow@gmail.com
|
|
8
|
-
License: Apache 2.0 with Commons Clause
|
|
5
|
+
Author-email: Oleg Polakow <olegpolakow@vectorbt.pro>
|
|
6
|
+
Project-URL: Homepage, https://github.com/polakowo/vectorbt
|
|
9
7
|
Classifier: Development Status :: 5 - Production/Stable
|
|
10
8
|
Classifier: Intended Audience :: Developers
|
|
11
9
|
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
12
|
-
Classifier: License :: Free for non-commercial use
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
17
10
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
12
|
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
14
|
Classifier: Operating System :: OS Independent
|
|
21
15
|
Classifier: Intended Audience :: Science/Research
|
|
22
16
|
Classifier: Topic :: Software Development
|
|
23
17
|
Classifier: Topic :: Office/Business :: Financial
|
|
24
18
|
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
25
|
-
Requires-Python: >=3.
|
|
19
|
+
Requires-Python: >=3.10
|
|
26
20
|
Description-Content-Type: text/markdown
|
|
27
21
|
License-File: LICENSE.md
|
|
28
|
-
Requires-Dist: numpy>=1.
|
|
29
|
-
Requires-Dist: pandas
|
|
22
|
+
Requires-Dist: numpy>=1.23
|
|
23
|
+
Requires-Dist: pandas<3.0,>=2.0
|
|
30
24
|
Requires-Dist: scipy
|
|
31
25
|
Requires-Dist: matplotlib
|
|
32
26
|
Requires-Dist: plotly>=4.12.0
|
|
33
27
|
Requires-Dist: ipywidgets>=7.0.0
|
|
34
|
-
Requires-Dist:
|
|
35
|
-
Requires-Dist: numba
|
|
36
|
-
Requires-Dist: numba>=0.57.0; python_version >= "3.11"
|
|
28
|
+
Requires-Dist: anywidget
|
|
29
|
+
Requires-Dist: numba>=0.60
|
|
37
30
|
Requires-Dist: dill
|
|
38
31
|
Requires-Dist: tqdm
|
|
39
32
|
Requires-Dist: dateparser
|
|
@@ -42,7 +35,6 @@ Requires-Dist: scikit-learn
|
|
|
42
35
|
Requires-Dist: schedule
|
|
43
36
|
Requires-Dist: requests
|
|
44
37
|
Requires-Dist: pytz
|
|
45
|
-
Requires-Dist: typing_extensions; python_version < "3.8"
|
|
46
38
|
Requires-Dist: mypy_extensions
|
|
47
39
|
Provides-Extra: full
|
|
48
40
|
Requires-Dist: yfinance>=0.2.22; extra == "full"
|
|
@@ -68,80 +60,93 @@ Requires-Dist: quantstats>=0.0.37; extra == "full-no-talib"
|
|
|
68
60
|
Provides-Extra: cov
|
|
69
61
|
Requires-Dist: pytest; extra == "cov"
|
|
70
62
|
Requires-Dist: pytest-cov; extra == "cov"
|
|
63
|
+
Requires-Dist: pytest-xdist; extra == "cov"
|
|
71
64
|
Requires-Dist: codecov; extra == "cov"
|
|
72
|
-
Dynamic: author
|
|
73
|
-
Dynamic: author-email
|
|
74
|
-
Dynamic: classifier
|
|
75
|
-
Dynamic: description
|
|
76
|
-
Dynamic: description-content-type
|
|
77
|
-
Dynamic: home-page
|
|
78
|
-
Dynamic: license
|
|
79
65
|
Dynamic: license-file
|
|
80
|
-
Dynamic: provides-extra
|
|
81
|
-
Dynamic: requires-dist
|
|
82
|
-
Dynamic: requires-python
|
|
83
|
-
Dynamic: summary
|
|
84
66
|
|
|
85
67
|
<div align="center">
|
|
86
|
-
<a href="https://vectorbt.pro/"
|
|
68
|
+
<a href="https://vectorbt.pro/" title="VectorBT PRO">
|
|
87
69
|
<img src="https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/logo/header-pro.svg" />
|
|
88
70
|
</a>
|
|
89
71
|
</div>
|
|
90
72
|
<div align="center">
|
|
91
|
-
<a href="https://vectorbt.dev/"
|
|
73
|
+
<a href="https://vectorbt.dev/" title="vectorbt">
|
|
92
74
|
<img src="https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/logo/header.svg" />
|
|
93
75
|
</a>
|
|
94
76
|
</div>
|
|
77
|
+
|
|
95
78
|
<br>
|
|
79
|
+
|
|
96
80
|
<p align="center">
|
|
97
|
-
<a href="https://pepy.tech/project/vectorbt"
|
|
81
|
+
<a href="https://pepy.tech/project/vectorbt" title="Downloads">
|
|
98
82
|
<img src="https://pepy.tech/badge/vectorbt" />
|
|
99
83
|
</a>
|
|
100
|
-
<a href="https://pypi.org/project/vectorbt"
|
|
84
|
+
<a href="https://pypi.org/project/vectorbt" title="PyPI">
|
|
101
85
|
<img src="https://img.shields.io/pypi/v/vectorbt?color=blueviolet" />
|
|
102
86
|
</a>
|
|
103
|
-
<a href="https://github.com/polakowo/vectorbt/blob/master/LICENSE.md"
|
|
104
|
-
|
|
87
|
+
<a href="https://github.com/polakowo/vectorbt/blob/master/LICENSE.md" title="License">
|
|
88
|
+
<img src="https://img.shields.io/badge/license-Fair%20Code-yellow" />
|
|
105
89
|
</a>
|
|
106
|
-
<a href="https://codecov.io/gh/polakowo/vectorbt"
|
|
90
|
+
<a href="https://codecov.io/gh/polakowo/vectorbt" title="codecov">
|
|
107
91
|
<img src="https://codecov.io/gh/polakowo/vectorbt/branch/master/graph/badge.svg?token=YTLNAI7PS3" />
|
|
108
92
|
</a>
|
|
109
|
-
<a href="https://vectorbt.dev/"
|
|
93
|
+
<a href="https://vectorbt.dev/" title="Website">
|
|
110
94
|
<img src="https://img.shields.io/website?url=https://vectorbt.dev/" />
|
|
111
95
|
</a>
|
|
112
|
-
<a href="https://mybinder.org/v2/gh/polakowo/vectorbt/HEAD?urlpath=lab"
|
|
96
|
+
<a href="https://mybinder.org/v2/gh/polakowo/vectorbt/HEAD?urlpath=lab" title="Launch Binder">
|
|
113
97
|
<img src="https://img.shields.io/badge/launch-binder-d6604a" />
|
|
114
98
|
</a>
|
|
115
|
-
<a href="https://gitter.im/vectorbt/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"
|
|
99
|
+
<a href="https://gitter.im/vectorbt/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge" title="Join the chat">
|
|
116
100
|
<img src="https://badges.gitter.im/vectorbt.svg" />
|
|
117
101
|
</a>
|
|
118
102
|
</p>
|
|
103
|
+
|
|
119
104
|
<p align="center">
|
|
120
|
-
<a href="https://pypi.org/project/vectorbt"
|
|
105
|
+
<a href="https://pypi.org/project/vectorbt" title="Supported Python versions">
|
|
121
106
|
<img src="https://img.shields.io/pypi/pyversions/vectorbt.svg?logo=python&logoColor=white" />
|
|
122
107
|
</a>
|
|
123
108
|
</p>
|
|
124
109
|
|
|
110
|
+
> [!TIP]
|
|
111
|
+
> *New in 0.28*:
|
|
112
|
+
>
|
|
113
|
+
> * Plotly 6 support
|
|
114
|
+
> * `ticker_kwargs` in `YFData`
|
|
115
|
+
> * Fixed Pandas TA dependency (→ [pandas-ta-classic](https://github.com/xgboosted/pandas-ta-classic)).
|
|
116
|
+
|
|
117
|
+
## :package: Installation
|
|
118
|
+
|
|
119
|
+
```sh
|
|
120
|
+
pip install -U vectorbt
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
To install optional dependencies as well:
|
|
124
|
+
|
|
125
|
+
```sh
|
|
126
|
+
pip install -U "vectorbt[full]"
|
|
127
|
+
```
|
|
128
|
+
|
|
125
129
|
## :sparkles: Usage
|
|
126
130
|
|
|
127
|
-
|
|
131
|
+
VectorBT lets you backtest strategies in just a few lines of Python.
|
|
128
132
|
|
|
129
|
-
*
|
|
133
|
+
* Profit from investing $100 in Bitcoin since 2014:
|
|
130
134
|
|
|
131
135
|
```python
|
|
132
136
|
import vectorbt as vbt
|
|
133
137
|
|
|
134
|
-
|
|
138
|
+
data = vbt.YFData.download("BTC-USD")
|
|
139
|
+
price = data.get("Close")
|
|
135
140
|
|
|
136
141
|
pf = vbt.Portfolio.from_holding(price, init_cash=100)
|
|
137
|
-
pf.total_profit()
|
|
142
|
+
print(pf.total_profit())
|
|
138
143
|
```
|
|
139
144
|
|
|
140
145
|
```plaintext
|
|
141
|
-
|
|
146
|
+
19501.10906763755
|
|
142
147
|
```
|
|
143
148
|
|
|
144
|
-
* Buy
|
|
149
|
+
* Buy when the 10-day SMA crosses above the 50-day SMA, and sell on the opposite crossover:
|
|
145
150
|
|
|
146
151
|
```python
|
|
147
152
|
fast_ma = vbt.MA.run(price, 10)
|
|
@@ -150,11 +155,11 @@ entries = fast_ma.ma_crossed_above(slow_ma)
|
|
|
150
155
|
exits = fast_ma.ma_crossed_below(slow_ma)
|
|
151
156
|
|
|
152
157
|
pf = vbt.Portfolio.from_signals(price, entries, exits, init_cash=100)
|
|
153
|
-
pf.total_profit()
|
|
158
|
+
print(pf.total_profit())
|
|
154
159
|
```
|
|
155
160
|
|
|
156
161
|
```plaintext
|
|
157
|
-
|
|
162
|
+
34417.80960086067
|
|
158
163
|
```
|
|
159
164
|
|
|
160
165
|
* Generate 1,000 strategies with random signals and test them on BTC and ETH:
|
|
@@ -163,104 +168,105 @@ pf.total_profit()
|
|
|
163
168
|
import numpy as np
|
|
164
169
|
|
|
165
170
|
symbols = ["BTC-USD", "ETH-USD"]
|
|
166
|
-
|
|
171
|
+
data = vbt.YFData.download(symbols, missing_index="drop")
|
|
172
|
+
price = data.get("Close")
|
|
167
173
|
|
|
168
174
|
n = np.random.randint(10, 101, size=1000).tolist()
|
|
169
175
|
pf = vbt.Portfolio.from_random_signals(price, n=n, init_cash=100, seed=42)
|
|
170
176
|
|
|
171
|
-
mean_expectancy = pf.trades.expectancy().groupby([
|
|
172
|
-
fig = mean_expectancy.unstack().vbt.scatterplot(xaxis_title=
|
|
177
|
+
mean_expectancy = pf.trades.expectancy().groupby(["randnx_n", "symbol"]).mean()
|
|
178
|
+
fig = mean_expectancy.unstack().vbt.scatterplot(xaxis_title="randnx_n", yaxis_title="mean_expectancy")
|
|
173
179
|
fig.show()
|
|
174
180
|
```
|
|
175
181
|
|
|
176
|
-

|
|
177
183
|
|
|
178
|
-
* For
|
|
179
|
-
dual SMA crossover strategy on BTC, USD, and LTC:
|
|
184
|
+
* For hyperparameter optimization fans: test 10,000 window combinations of a dual-SMA crossover strategy on BTC, ETH, and XRP:
|
|
180
185
|
|
|
181
186
|
```python
|
|
182
|
-
symbols = ["BTC-USD", "ETH-USD", "
|
|
183
|
-
|
|
187
|
+
symbols = ["BTC-USD", "ETH-USD", "XRP-USD"]
|
|
188
|
+
data = vbt.YFData.download(symbols, missing_index="drop")
|
|
189
|
+
price = data.get("Close")
|
|
184
190
|
|
|
185
191
|
windows = np.arange(2, 101)
|
|
186
|
-
fast_ma, slow_ma = vbt.MA.run_combs(price, window=windows, r=2, short_names=[
|
|
192
|
+
fast_ma, slow_ma = vbt.MA.run_combs(price, window=windows, r=2, short_names=["fast", "slow"])
|
|
187
193
|
entries = fast_ma.ma_crossed_above(slow_ma)
|
|
188
194
|
exits = fast_ma.ma_crossed_below(slow_ma)
|
|
189
195
|
|
|
190
|
-
|
|
191
|
-
pf = vbt.Portfolio.from_signals(price, entries, exits, **pf_kwargs)
|
|
196
|
+
pf = vbt.Portfolio.from_signals(price, entries, exits, size=np.inf, fees=0.001, freq="1D")
|
|
192
197
|
|
|
193
198
|
fig = pf.total_return().vbt.heatmap(
|
|
194
|
-
x_level=
|
|
195
|
-
trace_kwargs=dict(colorbar=dict(title=
|
|
199
|
+
x_level="fast_window", y_level="slow_window", slider_level="symbol", symmetric=True,
|
|
200
|
+
trace_kwargs=dict(colorbar=dict(title="Total return", tickformat="%")))
|
|
196
201
|
fig.show()
|
|
197
202
|
```
|
|
198
203
|
|
|
199
|
-
<img width="
|
|
204
|
+
<img width="750" src="https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/images/usage_dmac_heatmap.gif">
|
|
200
205
|
|
|
201
|
-
|
|
206
|
+
Inspect any strategy configuration by indexing with pandas:
|
|
202
207
|
|
|
203
208
|
```python
|
|
204
|
-
pf[(10, 20,
|
|
209
|
+
print(pf[(10, 20, "ETH-USD")].stats())
|
|
205
210
|
```
|
|
206
211
|
|
|
207
212
|
```plaintext
|
|
208
|
-
Start
|
|
209
|
-
End
|
|
210
|
-
Period
|
|
213
|
+
Start 2017-11-09 00:00:00+00:00
|
|
214
|
+
End 2026-01-03 00:00:00+00:00
|
|
215
|
+
Period 2978 days 00:00:00
|
|
211
216
|
Start Value 100.0
|
|
212
|
-
End Value
|
|
213
|
-
Total Return [%]
|
|
214
|
-
Benchmark Return [%]
|
|
217
|
+
End Value 1604.093789
|
|
218
|
+
Total Return [%] 1504.093789
|
|
219
|
+
Benchmark Return [%] 866.094127
|
|
215
220
|
Max Gross Exposure [%] 100.0
|
|
216
|
-
Total Fees Paid
|
|
221
|
+
Total Fees Paid 204.226289
|
|
217
222
|
Max Drawdown [%] 70.734951
|
|
218
|
-
Max Drawdown Duration
|
|
219
|
-
Total Trades
|
|
220
|
-
Total Closed Trades
|
|
223
|
+
Max Drawdown Duration 1095 days 00:00:00
|
|
224
|
+
Total Trades 81
|
|
225
|
+
Total Closed Trades 80
|
|
221
226
|
Total Open Trades 1
|
|
222
|
-
Open Trade PnL
|
|
223
|
-
Win Rate [%]
|
|
224
|
-
Best Trade [%]
|
|
225
|
-
Worst Trade [%] -
|
|
226
|
-
Avg Winning Trade [%]
|
|
227
|
-
Avg Losing Trade [%]
|
|
228
|
-
Avg Winning Trade Duration
|
|
229
|
-
Avg Losing Trade Duration
|
|
230
|
-
Profit Factor
|
|
231
|
-
Expectancy
|
|
232
|
-
Sharpe Ratio
|
|
233
|
-
Calmar Ratio
|
|
234
|
-
Omega Ratio
|
|
235
|
-
Sortino Ratio
|
|
227
|
+
Open Trade PnL -14.232533
|
|
228
|
+
Win Rate [%] 41.25
|
|
229
|
+
Best Trade [%] 120.511071
|
|
230
|
+
Worst Trade [%] -27.772271
|
|
231
|
+
Avg Winning Trade [%] 27.265519
|
|
232
|
+
Avg Losing Trade [%] -9.022864
|
|
233
|
+
Avg Winning Trade Duration 32 days 20:21:49.090909091
|
|
234
|
+
Avg Losing Trade Duration 8 days 16:51:03.829787234
|
|
235
|
+
Profit Factor 1.275515
|
|
236
|
+
Expectancy 18.979079
|
|
237
|
+
Sharpe Ratio 0.861945
|
|
238
|
+
Calmar Ratio 0.572758
|
|
239
|
+
Omega Ratio 1.20277
|
|
240
|
+
Sortino Ratio 1.301377
|
|
236
241
|
Name: (10, 20, ETH-USD), dtype: object
|
|
237
242
|
```
|
|
238
243
|
|
|
239
|
-
|
|
244
|
+
Same goes for plotting:
|
|
240
245
|
|
|
241
246
|
```python
|
|
242
|
-
pf[(10, 20,
|
|
247
|
+
pf[(10, 20, "ETH-USD")].plot().show()
|
|
243
248
|
```
|
|
244
249
|
|
|
245
|
-

|
|
246
251
|
|
|
247
|
-
It's not all about backtesting
|
|
252
|
+
It's not all about backtesting! VectorBT can also help with financial data analysis and visualization.
|
|
248
253
|
|
|
249
|
-
*
|
|
254
|
+
* Create a GIF that animates Bollinger Bands %B and bandwidth across multiple symbols:
|
|
250
255
|
|
|
251
256
|
```python
|
|
252
|
-
symbols = ["BTC-USD", "ETH-USD", "
|
|
253
|
-
|
|
257
|
+
symbols = ["BTC-USD", "ETH-USD", "XRP-USD"]
|
|
258
|
+
data = vbt.YFData.download(symbols, period="6mo", missing_index="drop")
|
|
259
|
+
price = data.get("Close")
|
|
254
260
|
bbands = vbt.BBANDS.run(price)
|
|
255
261
|
|
|
256
262
|
def plot(index, bbands):
|
|
257
263
|
bbands = bbands.loc[index]
|
|
258
264
|
fig = vbt.make_subplots(
|
|
259
265
|
rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.15,
|
|
260
|
-
subplot_titles=(
|
|
261
|
-
fig.update_layout(
|
|
266
|
+
subplot_titles=("%B", "Bandwidth"))
|
|
267
|
+
fig.update_layout(showlegend=False, width=750, height=400)
|
|
262
268
|
bbands.percent_b.vbt.ts_heatmap(
|
|
263
|
-
trace_kwargs=dict(zmin=0, zmid=0.5, zmax=1, colorscale=
|
|
269
|
+
trace_kwargs=dict(zmin=0, zmid=0.5, zmax=1, colorscale="Spectral", colorbar=dict(
|
|
264
270
|
y=(fig.layout.yaxis.domain[0] + fig.layout.yaxis.domain[1]) / 2, len=0.5
|
|
265
271
|
)), add_trace_kwargs=dict(row=1, col=1), fig=fig)
|
|
266
272
|
bbands.bandwidth.vbt.ts_heatmap(
|
|
@@ -269,7 +275,7 @@ def plot(index, bbands):
|
|
|
269
275
|
)), add_trace_kwargs=dict(row=2, col=1), fig=fig)
|
|
270
276
|
return fig
|
|
271
277
|
|
|
272
|
-
vbt.save_animation(
|
|
278
|
+
vbt.save_animation("bbands.gif", bbands.wrapper.index, plot, bbands, delta=90, step=3, fps=3)
|
|
273
279
|
```
|
|
274
280
|
|
|
275
281
|
```plaintext
|
|
@@ -278,39 +284,29 @@ vbt.save_animation('bbands.gif', bbands.wrapper.index, plot, bbands, delta=90, s
|
|
|
278
284
|
|
|
279
285
|
<img width="750" src="https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/images/usage_bbands.gif">
|
|
280
286
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
## Installation
|
|
284
|
-
|
|
285
|
-
```sh
|
|
286
|
-
pip install -U vectorbt
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
To also install optional dependencies:
|
|
287
|
+
This is just the tip of the iceberg. Visit the [website](https://vectorbt.dev/) to learn more.
|
|
290
288
|
|
|
291
|
-
|
|
292
|
-
pip install -U "vectorbt[full]"
|
|
293
|
-
```
|
|
289
|
+
## :link: Links
|
|
294
290
|
|
|
295
|
-
|
|
291
|
+
* [Website](https://vectorbt.dev/)
|
|
292
|
+
* [Colab Notebook](https://colab.research.google.com/drive/1ibqyrf6LPFlzRb6mkPpl3hxqL6ryNBXI?usp=sharing)
|
|
296
293
|
|
|
297
|
-
|
|
294
|
+
## :balance_scale: License
|
|
298
295
|
|
|
299
|
-
|
|
296
|
+
This work is [fair-code](http://faircode.io/) distributed under the [Apache 2.0 with Commons Clause](https://github.com/polakowo/vectorbt/blob/master/LICENSE.md) license.
|
|
300
297
|
|
|
301
|
-
|
|
302
|
-
The source code is open and everyone (individuals and organizations) can use it for free.
|
|
303
|
-
However, it is not allowed to sell products and services that are mostly just this software.
|
|
298
|
+
The source code is open, and everyone (individuals and organizations) may use it for free. However, you may not sell products or services that are primarily this software.
|
|
304
299
|
|
|
305
|
-
If you have
|
|
300
|
+
If you have questions or want to request a license exception, please [contact the author](mailto:olegpolakow@vectorbt.pro).
|
|
306
301
|
|
|
307
302
|
Installing optional dependencies may be subject to a more restrictive license.
|
|
308
303
|
|
|
309
|
-
## Star History
|
|
304
|
+
## :star: Star History
|
|
310
305
|
|
|
311
306
|
[](https://star-history.com/#polakowo/vectorbt&Timeline)
|
|
312
307
|
|
|
313
|
-
## Disclaimer
|
|
308
|
+
## :warning: Disclaimer
|
|
309
|
+
|
|
310
|
+
This software is for educational purposes only. Do not risk money you cannot afford to lose.
|
|
314
311
|
|
|
315
|
-
This software is for educational purposes only. Do not risk money which you are afraid to lose.
|
|
316
312
|
USE THE SOFTWARE AT YOUR OWN RISK. THE AUTHORS AND ALL AFFILIATES ASSUME NO RESPONSIBILITY FOR YOUR TRADING RESULTS.
|