summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--python-vectorbt.spec757
-rw-r--r--sources1
3 files changed, 759 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..5ac8ca7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/vectorbt-0.25.1.tar.gz
diff --git a/python-vectorbt.spec b/python-vectorbt.spec
new file mode 100644
index 0000000..3827531
--- /dev/null
+++ b/python-vectorbt.spec
@@ -0,0 +1,757 @@
+%global _empty_manifest_terminate_build 0
+Name: python-vectorbt
+Version: 0.25.1
+Release: 1
+Summary: Python library for backtesting and analyzing trading strategies at scale
+License: Apache 2.0 with Commons Clause
+URL: https://github.com/polakowo/vectorbt
+Source0: https://mirrors.nju.edu.cn/pypi/web/packages/2f/21/50e494335a5c39ce14578ec77ff00b7b732ab1d312655f67ec80f24b35e6/vectorbt-0.25.1.tar.gz
+BuildArch: noarch
+
+Requires: python3-numpy
+Requires: python3-pandas
+Requires: python3-scipy
+Requires: python3-matplotlib
+Requires: python3-plotly
+Requires: python3-ipywidgets
+Requires: python3-dill
+Requires: python3-tqdm
+Requires: python3-dateparser
+Requires: python3-imageio
+Requires: python3-scikit-learn
+Requires: python3-schedule
+Requires: python3-requests
+Requires: python3-pytz
+Requires: python3-mypy-extensions
+Requires: python3-numba
+Requires: python3-typing-extensions
+Requires: python3-numba
+Requires: python3-pytest
+Requires: python3-pytest-cov
+Requires: python3-codecov
+Requires: python3-yfinance
+Requires: python3-binance
+Requires: python3-ccxt
+Requires: python3-alpaca-trade-api
+Requires: python3-ray
+Requires: python3-ta
+Requires: python3-pandas-ta
+Requires: python3-TA-Lib
+Requires: python3-telegram-bot
+Requires: python3-quantstats
+
+%description
+<div align="center">
+ <a href="https://vectorbt.pro/" alt="https://vectorbt.pro/">
+ <img src="docs/docs/assets/logo/header-pro.svg" />
+ </a>
+</div>
+<div align="center">
+ <a href="https://vectorbt.dev/" alt="https://vectorbt.dev/">
+ <img src="docs/docs/assets/logo/header.svg" />
+ </a>
+</div>
+<br>
+<p align="center">
+ <a href="https://pypi.org/project/vectorbt" alt="Python Versions">
+ <img src="https://img.shields.io/pypi/pyversions/vectorbt.svg?logo=python&logoColor=white" /></a>
+ <a href="https://github.com/polakowo/vectorbt/blob/master/LICENSE.md" alt="License">
+ <img src="https://img.shields.io/badge/license-Fair%20Code-yellow" /></a>
+ <a href="https://pypi.org/project/vectorbt" alt="PyPi">
+ <img src="https://img.shields.io/pypi/v/vectorbt?color=blueviolet" /></a>
+ <a href="https://codecov.io/gh/polakowo/vectorbt" alt="codecov">
+ <img src="https://codecov.io/gh/polakowo/vectorbt/branch/master/graph/badge.svg?token=YTLNAI7PS3" /></a>
+ <a href="https://vectorbt.dev/" alt="Website">
+ <img src="https://img.shields.io/website?url=https://vectorbt.dev/" /></a>
+ <a href="https://pepy.tech/project/vectorbt" alt="Downloads">
+ <img src="https://pepy.tech/badge/vectorbt" /></a>
+ <a href="https://mybinder.org/v2/gh/polakowo/vectorbt/HEAD?urlpath=lab" alt="Binder">
+ <img src="https://img.shields.io/badge/launch-binder-d6604a" /></a>
+ <a href="https://gitter.im/vectorbt/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge" alt="Join the chat at https://gitter.im/vectorbt/community">
+ <img src="https://badges.gitter.im/vectorbt.svg" /></a>
+</p>
+
+## :sparkles: Usage
+
+vectorbt allows you to easily backtest strategies with a couple of lines of Python code.
+
+* Here is how much profit we would have made if we invested $100 into Bitcoin in 2014:
+
+```python
+import vectorbt as vbt
+
+price = vbt.YFData.download('BTC-USD').get('Close')
+
+pf = vbt.Portfolio.from_holding(price, init_cash=100)
+pf.total_profit()
+```
+
+```plaintext
+8961.008555963961
+```
+
+* Buy whenever 10-day SMA crosses above 50-day SMA and sell when opposite:
+
+```python
+fast_ma = vbt.MA.run(price, 10)
+slow_ma = vbt.MA.run(price, 50)
+entries = fast_ma.ma_crossed_above(slow_ma)
+exits = fast_ma.ma_crossed_below(slow_ma)
+
+pf = vbt.Portfolio.from_signals(price, entries, exits, init_cash=100)
+pf.total_profit()
+```
+
+```plaintext
+16423.251963801864
+```
+
+* Generate 1,000 strategies with random signals and test them on BTC and ETH:
+
+```python
+import numpy as np
+
+symbols = ["BTC-USD", "ETH-USD"]
+price = vbt.YFData.download(symbols, missing_index='drop').get('Close')
+
+n = np.random.randint(10, 101, size=1000).tolist()
+pf = vbt.Portfolio.from_random_signals(price, n=n, init_cash=100, seed=42)
+
+mean_expectancy = pf.trades.expectancy().groupby(['randnx_n', 'symbol']).mean()
+fig = mean_expectancy.unstack().vbt.scatterplot(xaxis_title='randnx_n', yaxis_title='mean_expectancy')
+fig.show()
+```
+
+![rand_scatter.svg](https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/images/usage_rand_scatter.svg)
+
+* For fans of hyperparameter optimization: here is a snippet for testing 10,000 window combinations of a
+dual SMA crossover strategy on BTC, USD, and LTC:
+
+```python
+symbols = ["BTC-USD", "ETH-USD", "LTC-USD"]
+price = vbt.YFData.download(symbols, missing_index='drop').get('Close')
+
+windows = np.arange(2, 101)
+fast_ma, slow_ma = vbt.MA.run_combs(price, window=windows, r=2, short_names=['fast', 'slow'])
+entries = fast_ma.ma_crossed_above(slow_ma)
+exits = fast_ma.ma_crossed_below(slow_ma)
+
+pf_kwargs = dict(size=np.inf, fees=0.001, freq='1D')
+pf = vbt.Portfolio.from_signals(price, entries, exits, **pf_kwargs)
+
+fig = pf.total_return().vbt.heatmap(
+ x_level='fast_window', y_level='slow_window', slider_level='symbol', symmetric=True,
+ trace_kwargs=dict(colorbar=dict(title='Total return', tickformat='%')))
+fig.show()
+```
+
+<img width="650" src="https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/images/usage_dmac_heatmap.gif">
+
+Digging into each strategy configuration is as simple as indexing with pandas:
+
+```python
+pf[(10, 20, 'ETH-USD')].stats()
+```
+
+```plaintext
+Start 2015-08-07 00:00:00+00:00
+End 2021-08-01 00:00:00+00:00
+Period 2183 days 00:00:00
+Start Value 100.0
+End Value 620402.791485
+Total Return [%] 620302.791485
+Benchmark Return [%] 92987.961948
+Max Gross Exposure [%] 100.0
+Total Fees Paid 10991.676981
+Max Drawdown [%] 70.734951
+Max Drawdown Duration 760 days 00:00:00
+Total Trades 54
+Total Closed Trades 53
+Total Open Trades 1
+Open Trade PnL 67287.940601
+Win Rate [%] 52.830189
+Best Trade [%] 1075.803607
+Worst Trade [%] -29.593414
+Avg Winning Trade [%] 95.695343
+Avg Losing Trade [%] -11.890246
+Avg Winning Trade Duration 35 days 23:08:34.285714286
+Avg Losing Trade Duration 8 days 00:00:00
+Profit Factor 2.651143
+Expectancy 10434.24247
+Sharpe Ratio 2.041211
+Calmar Ratio 4.6747
+Omega Ratio 1.547013
+Sortino Ratio 3.519894
+Name: (10, 20, ETH-USD), dtype: object
+```
+
+The same for plotting:
+
+```python
+pf[(10, 20, 'ETH-USD')].plot().show()
+```
+
+![dmac_portfolio.svg](https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/images/usage_dmac_portfolio.svg)
+
+It's not all about backtesting - vectorbt can be used to facilitate financial data analysis and visualization.
+
+* Let's generate a GIF that animates the %B and bandwidth of Bollinger Bands for different symbols:
+
+```python
+symbols = ["BTC-USD", "ETH-USD", "ADA-USD"]
+price = vbt.YFData.download(symbols, period='6mo', missing_index='drop').get('Close')
+bbands = vbt.BBANDS.run(price)
+
+def plot(index, bbands):
+ bbands = bbands.loc[index]
+ fig = vbt.make_subplots(
+ rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.15,
+ subplot_titles=('%B', 'Bandwidth'))
+ fig.update_layout(template='vbt_dark', showlegend=False, width=750, height=400)
+ bbands.percent_b.vbt.ts_heatmap(
+ trace_kwargs=dict(zmin=0, zmid=0.5, zmax=1, colorscale='Spectral', colorbar=dict(
+ y=(fig.layout.yaxis.domain[0] + fig.layout.yaxis.domain[1]) / 2, len=0.5
+ )), add_trace_kwargs=dict(row=1, col=1), fig=fig)
+ bbands.bandwidth.vbt.ts_heatmap(
+ trace_kwargs=dict(colorbar=dict(
+ y=(fig.layout.yaxis2.domain[0] + fig.layout.yaxis2.domain[1]) / 2, len=0.5
+ )), add_trace_kwargs=dict(row=2, col=1), fig=fig)
+ return fig
+
+vbt.save_animation('bbands.gif', bbands.wrapper.index, plot, bbands, delta=90, step=3, fps=3)
+```
+
+```plaintext
+100%|██████████| 31/31 [00:21<00:00, 1.21it/s]
+```
+
+<img width="750" src="https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/images/usage_bbands.gif">
+
+And this is just the tip of the iceberg of what's possible. Check out the [website](https://vectorbt.dev/) to learn more.
+
+## Installation
+
+```sh
+pip install -U vectorbt
+```
+
+To also install optional dependencies:
+
+```sh
+pip install -U "vectorbt[full]"
+```
+
+## License
+
+This work is [fair-code](http://faircode.io/) distributed under [Apache 2.0 with Commons Clause](https://github.com/polakowo/vectorbt/blob/master/LICENSE.md) license.
+The source code is open and everyone (individuals and organizations) can use it for free.
+However, it is not allowed to sell products and services that are mostly just this software.
+
+If you have any questions about this or want to apply for a license exception, please [contact the author](mailto:olegpolakow@gmail.com).
+
+Installing optional dependencies may be subject to a more restrictive license.
+
+## Star History
+
+[![Star History Chart](https://api.star-history.com/svg?repos=polakowo/vectorbt&type=Timeline)](https://star-history.com/#polakowo/vectorbt&Timeline)
+
+## Disclaimer
+
+This software is for educational purposes only. Do not risk money which you are afraid to lose.
+USE THE SOFTWARE AT YOUR OWN RISK. THE AUTHORS AND ALL AFFILIATES ASSUME NO RESPONSIBILITY FOR YOUR TRADING RESULTS.
+
+
+%package -n python3-vectorbt
+Summary: Python library for backtesting and analyzing trading strategies at scale
+Provides: python-vectorbt
+BuildRequires: python3-devel
+BuildRequires: python3-setuptools
+BuildRequires: python3-pip
+%description -n python3-vectorbt
+<div align="center">
+ <a href="https://vectorbt.pro/" alt="https://vectorbt.pro/">
+ <img src="docs/docs/assets/logo/header-pro.svg" />
+ </a>
+</div>
+<div align="center">
+ <a href="https://vectorbt.dev/" alt="https://vectorbt.dev/">
+ <img src="docs/docs/assets/logo/header.svg" />
+ </a>
+</div>
+<br>
+<p align="center">
+ <a href="https://pypi.org/project/vectorbt" alt="Python Versions">
+ <img src="https://img.shields.io/pypi/pyversions/vectorbt.svg?logo=python&logoColor=white" /></a>
+ <a href="https://github.com/polakowo/vectorbt/blob/master/LICENSE.md" alt="License">
+ <img src="https://img.shields.io/badge/license-Fair%20Code-yellow" /></a>
+ <a href="https://pypi.org/project/vectorbt" alt="PyPi">
+ <img src="https://img.shields.io/pypi/v/vectorbt?color=blueviolet" /></a>
+ <a href="https://codecov.io/gh/polakowo/vectorbt" alt="codecov">
+ <img src="https://codecov.io/gh/polakowo/vectorbt/branch/master/graph/badge.svg?token=YTLNAI7PS3" /></a>
+ <a href="https://vectorbt.dev/" alt="Website">
+ <img src="https://img.shields.io/website?url=https://vectorbt.dev/" /></a>
+ <a href="https://pepy.tech/project/vectorbt" alt="Downloads">
+ <img src="https://pepy.tech/badge/vectorbt" /></a>
+ <a href="https://mybinder.org/v2/gh/polakowo/vectorbt/HEAD?urlpath=lab" alt="Binder">
+ <img src="https://img.shields.io/badge/launch-binder-d6604a" /></a>
+ <a href="https://gitter.im/vectorbt/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge" alt="Join the chat at https://gitter.im/vectorbt/community">
+ <img src="https://badges.gitter.im/vectorbt.svg" /></a>
+</p>
+
+## :sparkles: Usage
+
+vectorbt allows you to easily backtest strategies with a couple of lines of Python code.
+
+* Here is how much profit we would have made if we invested $100 into Bitcoin in 2014:
+
+```python
+import vectorbt as vbt
+
+price = vbt.YFData.download('BTC-USD').get('Close')
+
+pf = vbt.Portfolio.from_holding(price, init_cash=100)
+pf.total_profit()
+```
+
+```plaintext
+8961.008555963961
+```
+
+* Buy whenever 10-day SMA crosses above 50-day SMA and sell when opposite:
+
+```python
+fast_ma = vbt.MA.run(price, 10)
+slow_ma = vbt.MA.run(price, 50)
+entries = fast_ma.ma_crossed_above(slow_ma)
+exits = fast_ma.ma_crossed_below(slow_ma)
+
+pf = vbt.Portfolio.from_signals(price, entries, exits, init_cash=100)
+pf.total_profit()
+```
+
+```plaintext
+16423.251963801864
+```
+
+* Generate 1,000 strategies with random signals and test them on BTC and ETH:
+
+```python
+import numpy as np
+
+symbols = ["BTC-USD", "ETH-USD"]
+price = vbt.YFData.download(symbols, missing_index='drop').get('Close')
+
+n = np.random.randint(10, 101, size=1000).tolist()
+pf = vbt.Portfolio.from_random_signals(price, n=n, init_cash=100, seed=42)
+
+mean_expectancy = pf.trades.expectancy().groupby(['randnx_n', 'symbol']).mean()
+fig = mean_expectancy.unstack().vbt.scatterplot(xaxis_title='randnx_n', yaxis_title='mean_expectancy')
+fig.show()
+```
+
+![rand_scatter.svg](https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/images/usage_rand_scatter.svg)
+
+* For fans of hyperparameter optimization: here is a snippet for testing 10,000 window combinations of a
+dual SMA crossover strategy on BTC, USD, and LTC:
+
+```python
+symbols = ["BTC-USD", "ETH-USD", "LTC-USD"]
+price = vbt.YFData.download(symbols, missing_index='drop').get('Close')
+
+windows = np.arange(2, 101)
+fast_ma, slow_ma = vbt.MA.run_combs(price, window=windows, r=2, short_names=['fast', 'slow'])
+entries = fast_ma.ma_crossed_above(slow_ma)
+exits = fast_ma.ma_crossed_below(slow_ma)
+
+pf_kwargs = dict(size=np.inf, fees=0.001, freq='1D')
+pf = vbt.Portfolio.from_signals(price, entries, exits, **pf_kwargs)
+
+fig = pf.total_return().vbt.heatmap(
+ x_level='fast_window', y_level='slow_window', slider_level='symbol', symmetric=True,
+ trace_kwargs=dict(colorbar=dict(title='Total return', tickformat='%')))
+fig.show()
+```
+
+<img width="650" src="https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/images/usage_dmac_heatmap.gif">
+
+Digging into each strategy configuration is as simple as indexing with pandas:
+
+```python
+pf[(10, 20, 'ETH-USD')].stats()
+```
+
+```plaintext
+Start 2015-08-07 00:00:00+00:00
+End 2021-08-01 00:00:00+00:00
+Period 2183 days 00:00:00
+Start Value 100.0
+End Value 620402.791485
+Total Return [%] 620302.791485
+Benchmark Return [%] 92987.961948
+Max Gross Exposure [%] 100.0
+Total Fees Paid 10991.676981
+Max Drawdown [%] 70.734951
+Max Drawdown Duration 760 days 00:00:00
+Total Trades 54
+Total Closed Trades 53
+Total Open Trades 1
+Open Trade PnL 67287.940601
+Win Rate [%] 52.830189
+Best Trade [%] 1075.803607
+Worst Trade [%] -29.593414
+Avg Winning Trade [%] 95.695343
+Avg Losing Trade [%] -11.890246
+Avg Winning Trade Duration 35 days 23:08:34.285714286
+Avg Losing Trade Duration 8 days 00:00:00
+Profit Factor 2.651143
+Expectancy 10434.24247
+Sharpe Ratio 2.041211
+Calmar Ratio 4.6747
+Omega Ratio 1.547013
+Sortino Ratio 3.519894
+Name: (10, 20, ETH-USD), dtype: object
+```
+
+The same for plotting:
+
+```python
+pf[(10, 20, 'ETH-USD')].plot().show()
+```
+
+![dmac_portfolio.svg](https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/images/usage_dmac_portfolio.svg)
+
+It's not all about backtesting - vectorbt can be used to facilitate financial data analysis and visualization.
+
+* Let's generate a GIF that animates the %B and bandwidth of Bollinger Bands for different symbols:
+
+```python
+symbols = ["BTC-USD", "ETH-USD", "ADA-USD"]
+price = vbt.YFData.download(symbols, period='6mo', missing_index='drop').get('Close')
+bbands = vbt.BBANDS.run(price)
+
+def plot(index, bbands):
+ bbands = bbands.loc[index]
+ fig = vbt.make_subplots(
+ rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.15,
+ subplot_titles=('%B', 'Bandwidth'))
+ fig.update_layout(template='vbt_dark', showlegend=False, width=750, height=400)
+ bbands.percent_b.vbt.ts_heatmap(
+ trace_kwargs=dict(zmin=0, zmid=0.5, zmax=1, colorscale='Spectral', colorbar=dict(
+ y=(fig.layout.yaxis.domain[0] + fig.layout.yaxis.domain[1]) / 2, len=0.5
+ )), add_trace_kwargs=dict(row=1, col=1), fig=fig)
+ bbands.bandwidth.vbt.ts_heatmap(
+ trace_kwargs=dict(colorbar=dict(
+ y=(fig.layout.yaxis2.domain[0] + fig.layout.yaxis2.domain[1]) / 2, len=0.5
+ )), add_trace_kwargs=dict(row=2, col=1), fig=fig)
+ return fig
+
+vbt.save_animation('bbands.gif', bbands.wrapper.index, plot, bbands, delta=90, step=3, fps=3)
+```
+
+```plaintext
+100%|██████████| 31/31 [00:21<00:00, 1.21it/s]
+```
+
+<img width="750" src="https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/images/usage_bbands.gif">
+
+And this is just the tip of the iceberg of what's possible. Check out the [website](https://vectorbt.dev/) to learn more.
+
+## Installation
+
+```sh
+pip install -U vectorbt
+```
+
+To also install optional dependencies:
+
+```sh
+pip install -U "vectorbt[full]"
+```
+
+## License
+
+This work is [fair-code](http://faircode.io/) distributed under [Apache 2.0 with Commons Clause](https://github.com/polakowo/vectorbt/blob/master/LICENSE.md) license.
+The source code is open and everyone (individuals and organizations) can use it for free.
+However, it is not allowed to sell products and services that are mostly just this software.
+
+If you have any questions about this or want to apply for a license exception, please [contact the author](mailto:olegpolakow@gmail.com).
+
+Installing optional dependencies may be subject to a more restrictive license.
+
+## Star History
+
+[![Star History Chart](https://api.star-history.com/svg?repos=polakowo/vectorbt&type=Timeline)](https://star-history.com/#polakowo/vectorbt&Timeline)
+
+## Disclaimer
+
+This software is for educational purposes only. Do not risk money which you are afraid to lose.
+USE THE SOFTWARE AT YOUR OWN RISK. THE AUTHORS AND ALL AFFILIATES ASSUME NO RESPONSIBILITY FOR YOUR TRADING RESULTS.
+
+
+%package help
+Summary: Development documents and examples for vectorbt
+Provides: python3-vectorbt-doc
+%description help
+<div align="center">
+ <a href="https://vectorbt.pro/" alt="https://vectorbt.pro/">
+ <img src="docs/docs/assets/logo/header-pro.svg" />
+ </a>
+</div>
+<div align="center">
+ <a href="https://vectorbt.dev/" alt="https://vectorbt.dev/">
+ <img src="docs/docs/assets/logo/header.svg" />
+ </a>
+</div>
+<br>
+<p align="center">
+ <a href="https://pypi.org/project/vectorbt" alt="Python Versions">
+ <img src="https://img.shields.io/pypi/pyversions/vectorbt.svg?logo=python&logoColor=white" /></a>
+ <a href="https://github.com/polakowo/vectorbt/blob/master/LICENSE.md" alt="License">
+ <img src="https://img.shields.io/badge/license-Fair%20Code-yellow" /></a>
+ <a href="https://pypi.org/project/vectorbt" alt="PyPi">
+ <img src="https://img.shields.io/pypi/v/vectorbt?color=blueviolet" /></a>
+ <a href="https://codecov.io/gh/polakowo/vectorbt" alt="codecov">
+ <img src="https://codecov.io/gh/polakowo/vectorbt/branch/master/graph/badge.svg?token=YTLNAI7PS3" /></a>
+ <a href="https://vectorbt.dev/" alt="Website">
+ <img src="https://img.shields.io/website?url=https://vectorbt.dev/" /></a>
+ <a href="https://pepy.tech/project/vectorbt" alt="Downloads">
+ <img src="https://pepy.tech/badge/vectorbt" /></a>
+ <a href="https://mybinder.org/v2/gh/polakowo/vectorbt/HEAD?urlpath=lab" alt="Binder">
+ <img src="https://img.shields.io/badge/launch-binder-d6604a" /></a>
+ <a href="https://gitter.im/vectorbt/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge" alt="Join the chat at https://gitter.im/vectorbt/community">
+ <img src="https://badges.gitter.im/vectorbt.svg" /></a>
+</p>
+
+## :sparkles: Usage
+
+vectorbt allows you to easily backtest strategies with a couple of lines of Python code.
+
+* Here is how much profit we would have made if we invested $100 into Bitcoin in 2014:
+
+```python
+import vectorbt as vbt
+
+price = vbt.YFData.download('BTC-USD').get('Close')
+
+pf = vbt.Portfolio.from_holding(price, init_cash=100)
+pf.total_profit()
+```
+
+```plaintext
+8961.008555963961
+```
+
+* Buy whenever 10-day SMA crosses above 50-day SMA and sell when opposite:
+
+```python
+fast_ma = vbt.MA.run(price, 10)
+slow_ma = vbt.MA.run(price, 50)
+entries = fast_ma.ma_crossed_above(slow_ma)
+exits = fast_ma.ma_crossed_below(slow_ma)
+
+pf = vbt.Portfolio.from_signals(price, entries, exits, init_cash=100)
+pf.total_profit()
+```
+
+```plaintext
+16423.251963801864
+```
+
+* Generate 1,000 strategies with random signals and test them on BTC and ETH:
+
+```python
+import numpy as np
+
+symbols = ["BTC-USD", "ETH-USD"]
+price = vbt.YFData.download(symbols, missing_index='drop').get('Close')
+
+n = np.random.randint(10, 101, size=1000).tolist()
+pf = vbt.Portfolio.from_random_signals(price, n=n, init_cash=100, seed=42)
+
+mean_expectancy = pf.trades.expectancy().groupby(['randnx_n', 'symbol']).mean()
+fig = mean_expectancy.unstack().vbt.scatterplot(xaxis_title='randnx_n', yaxis_title='mean_expectancy')
+fig.show()
+```
+
+![rand_scatter.svg](https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/images/usage_rand_scatter.svg)
+
+* For fans of hyperparameter optimization: here is a snippet for testing 10,000 window combinations of a
+dual SMA crossover strategy on BTC, USD, and LTC:
+
+```python
+symbols = ["BTC-USD", "ETH-USD", "LTC-USD"]
+price = vbt.YFData.download(symbols, missing_index='drop').get('Close')
+
+windows = np.arange(2, 101)
+fast_ma, slow_ma = vbt.MA.run_combs(price, window=windows, r=2, short_names=['fast', 'slow'])
+entries = fast_ma.ma_crossed_above(slow_ma)
+exits = fast_ma.ma_crossed_below(slow_ma)
+
+pf_kwargs = dict(size=np.inf, fees=0.001, freq='1D')
+pf = vbt.Portfolio.from_signals(price, entries, exits, **pf_kwargs)
+
+fig = pf.total_return().vbt.heatmap(
+ x_level='fast_window', y_level='slow_window', slider_level='symbol', symmetric=True,
+ trace_kwargs=dict(colorbar=dict(title='Total return', tickformat='%')))
+fig.show()
+```
+
+<img width="650" src="https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/images/usage_dmac_heatmap.gif">
+
+Digging into each strategy configuration is as simple as indexing with pandas:
+
+```python
+pf[(10, 20, 'ETH-USD')].stats()
+```
+
+```plaintext
+Start 2015-08-07 00:00:00+00:00
+End 2021-08-01 00:00:00+00:00
+Period 2183 days 00:00:00
+Start Value 100.0
+End Value 620402.791485
+Total Return [%] 620302.791485
+Benchmark Return [%] 92987.961948
+Max Gross Exposure [%] 100.0
+Total Fees Paid 10991.676981
+Max Drawdown [%] 70.734951
+Max Drawdown Duration 760 days 00:00:00
+Total Trades 54
+Total Closed Trades 53
+Total Open Trades 1
+Open Trade PnL 67287.940601
+Win Rate [%] 52.830189
+Best Trade [%] 1075.803607
+Worst Trade [%] -29.593414
+Avg Winning Trade [%] 95.695343
+Avg Losing Trade [%] -11.890246
+Avg Winning Trade Duration 35 days 23:08:34.285714286
+Avg Losing Trade Duration 8 days 00:00:00
+Profit Factor 2.651143
+Expectancy 10434.24247
+Sharpe Ratio 2.041211
+Calmar Ratio 4.6747
+Omega Ratio 1.547013
+Sortino Ratio 3.519894
+Name: (10, 20, ETH-USD), dtype: object
+```
+
+The same for plotting:
+
+```python
+pf[(10, 20, 'ETH-USD')].plot().show()
+```
+
+![dmac_portfolio.svg](https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/images/usage_dmac_portfolio.svg)
+
+It's not all about backtesting - vectorbt can be used to facilitate financial data analysis and visualization.
+
+* Let's generate a GIF that animates the %B and bandwidth of Bollinger Bands for different symbols:
+
+```python
+symbols = ["BTC-USD", "ETH-USD", "ADA-USD"]
+price = vbt.YFData.download(symbols, period='6mo', missing_index='drop').get('Close')
+bbands = vbt.BBANDS.run(price)
+
+def plot(index, bbands):
+ bbands = bbands.loc[index]
+ fig = vbt.make_subplots(
+ rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.15,
+ subplot_titles=('%B', 'Bandwidth'))
+ fig.update_layout(template='vbt_dark', showlegend=False, width=750, height=400)
+ bbands.percent_b.vbt.ts_heatmap(
+ trace_kwargs=dict(zmin=0, zmid=0.5, zmax=1, colorscale='Spectral', colorbar=dict(
+ y=(fig.layout.yaxis.domain[0] + fig.layout.yaxis.domain[1]) / 2, len=0.5
+ )), add_trace_kwargs=dict(row=1, col=1), fig=fig)
+ bbands.bandwidth.vbt.ts_heatmap(
+ trace_kwargs=dict(colorbar=dict(
+ y=(fig.layout.yaxis2.domain[0] + fig.layout.yaxis2.domain[1]) / 2, len=0.5
+ )), add_trace_kwargs=dict(row=2, col=1), fig=fig)
+ return fig
+
+vbt.save_animation('bbands.gif', bbands.wrapper.index, plot, bbands, delta=90, step=3, fps=3)
+```
+
+```plaintext
+100%|██████████| 31/31 [00:21<00:00, 1.21it/s]
+```
+
+<img width="750" src="https://raw.githubusercontent.com/polakowo/vectorbt/master/docs/docs/assets/images/usage_bbands.gif">
+
+And this is just the tip of the iceberg of what's possible. Check out the [website](https://vectorbt.dev/) to learn more.
+
+## Installation
+
+```sh
+pip install -U vectorbt
+```
+
+To also install optional dependencies:
+
+```sh
+pip install -U "vectorbt[full]"
+```
+
+## License
+
+This work is [fair-code](http://faircode.io/) distributed under [Apache 2.0 with Commons Clause](https://github.com/polakowo/vectorbt/blob/master/LICENSE.md) license.
+The source code is open and everyone (individuals and organizations) can use it for free.
+However, it is not allowed to sell products and services that are mostly just this software.
+
+If you have any questions about this or want to apply for a license exception, please [contact the author](mailto:olegpolakow@gmail.com).
+
+Installing optional dependencies may be subject to a more restrictive license.
+
+## Star History
+
+[![Star History Chart](https://api.star-history.com/svg?repos=polakowo/vectorbt&type=Timeline)](https://star-history.com/#polakowo/vectorbt&Timeline)
+
+## Disclaimer
+
+This software is for educational purposes only. Do not risk money which you are afraid to lose.
+USE THE SOFTWARE AT YOUR OWN RISK. THE AUTHORS AND ALL AFFILIATES ASSUME NO RESPONSIBILITY FOR YOUR TRADING RESULTS.
+
+
+%prep
+%autosetup -n vectorbt-0.25.1
+
+%build
+%py3_build
+
+%install
+%py3_install
+install -d -m755 %{buildroot}/%{_pkgdocdir}
+if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
+if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
+if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
+if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
+pushd %{buildroot}
+if [ -d usr/lib ]; then
+ find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/lib64 ]; then
+ find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/bin ]; then
+ find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/sbin ]; then
+ find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+touch doclist.lst
+if [ -d usr/share/man ]; then
+ find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst
+fi
+popd
+mv %{buildroot}/filelist.lst .
+mv %{buildroot}/doclist.lst .
+
+%files -n python3-vectorbt -f filelist.lst
+%dir %{python3_sitelib}/*
+
+%files help -f doclist.lst
+%{_docdir}/*
+
+%changelog
+* Fri May 05 2023 Python_Bot <Python_Bot@openeuler.org> - 0.25.1-1
+- Package Spec generated
diff --git a/sources b/sources
new file mode 100644
index 0000000..deb3ee0
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+43b5e7194e23d0d20b257af7a164df51 vectorbt-0.25.1.tar.gz