Skip to main content

portbt

portbt is a Python library designed to make backtesting a custom portfolio of assets easy and intuitive. With PortBT, you can test a range of rebalancing strategies and asset allocations using just a few lines of code.

Features

  • Simple and intuitive code
  • Flexible rebalancing options

Getting Started

To get started with PortBT, simply install the library using pip

pip install portbt

Import it into your Python project. From there, you just have to create a Portfolio object with the asset prices to define your portfolio.

import portbt as pbt

# sample from brazil, so decimal "," and sep ";"
prices = pd.read_csv('sample/prices.csv', sep=';', decimal=',')
prices.index = pd.to_datetime(prices.index) # index has to be datetime
prices[prices.columns] = prices[prices.columns].astype(float)
prices.name = 'prices'
prices.index.name = 'date'

print(prices)

Output

                BBAS3     BOVA11      ITUB4      PETR4     SMAL11      VALE3
date                                                                        
2008-11-28   5.848646  36.595901   6.496692   7.174176  23.760300  13.265061
2008-12-01   5.848646  34.744900   6.289404   6.580500  22.656500  12.286927
2008-12-02   5.828202  35.001598   6.447920   6.544737  22.606501  11.829182
2008-12-03   5.848646  35.293800   6.511325   6.905950  22.426001  11.983371
2008-12-04   5.971348  35.122101   6.567414   6.652028  22.636900  11.607532
...               ...        ...        ...        ...        ...        ...
2023-04-03  38.650002  98.300003  24.030001  24.490000  86.500000  80.309998
2023-04-04  39.290001  98.510002  24.510000  24.270000  87.000000  78.040001
2023-04-05  39.150002  97.629997  24.490000  24.350000  85.650002  76.889999
2023-04-06  39.020000  97.589996  24.410000  24.000000  85.879997  76.750000
2023-04-10  39.040001  98.660004  24.670000  24.510000  86.349998  78.230003

Creating the portfolio and backtesting

portfolio = pbt.Portfolio(prices)

backtest = portfolio.run_backtest(rebalance=False)

# backtest.prices -> prices for each asset, "raw data"
# backtest.values -> values for each asset (starting capital = 1)
# backtest.exposure -> exposure for each asset
# backtest.result -> backtest result, starting from 1
# backtest.all_dates -> all dates for the backtesting, if needed
# backtest.rebal_dates -> rebalace dates only

# example
print(backtest.exposure)

Output

               BBAS3    BOVA11     ITUB4     PETR4    SMAL11     VALE3
date                                                                  
2008-11-28  0.166667  0.166667  0.166667  0.166667  0.166667  0.166667
2008-12-01  0.174991  0.166140  0.169408  0.160510  0.166862  0.162088
2008-12-02  0.174798  0.167769  0.174094  0.160021  0.166893  0.156424
2008-12-03  0.173115  0.166956  0.173505  0.166643  0.163393  0.156388
2008-12-04  0.177667  0.167009  0.175911  0.161351  0.165789  0.152272
...              ...       ...       ...       ...       ...       ...
2023-04-03  0.253178  0.102909  0.141708  0.130782  0.139475  0.231949
2023-04-04  0.257288  0.103096  0.144492  0.129566  0.140236  0.225321
2023-04-05  0.258185  0.102898  0.145396  0.130913  0.139037  0.223571
2023-04-06  0.258177  0.103195  0.145399  0.129457  0.139871  0.223901
2023-04-10  0.255589  0.103228  0.145400  0.130815  0.139155  0.225814

Portfolio backtesting - main function

Portfolio.run_backtest() -> Backtest

    Parameters:

        - rebalance: bool (required)
            If 'True', the backtest will rebalance itself.

        - weights: str or dict, default 'ew'
            If 'dict', than it is the weight for each asset (number between 0 and 1),
            The sum can't be different than one.
            Example:
                asset_weights = {
                    'asset1': 0.3,
                    'asset2': 0.2,
                    'asset3': 0.5,
                }
            If str (has to be 'ew'), runs the backtest using equal weight for all 
            assets (1 / number of assets).

        - rebal_freq: str, default '1M'
            Rebalance frequency. Has the same valid inputs as pandas.DataFrame.resample() 
            function.

TODO

  • Performance metrics and visualizations
  • Reports
  • Yahoo Finance implementation

Metadata

Release files for portbt 0.1.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for portbt 0.1.8
File Size Uploaded Provenance Actions
portbt-0.1.8.tar.gz 5.4 kB Without provenance Details for portbt-0.1.8.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for portbt 0.1.8
File Interpreter ABI Platform Actions
portbt-0.1.8-py3-none-any.whl Python 3 none any Details for portbt-0.1.8-py3-none-any.whl

Total release size: 11.8 kB

Release files / portbt-0.1.8.tar.gz

Download URL portbt-0.1.8.tar.gz
Size 5.4 kB
Tags Source
SHA-256 checksum
How to use checksums
852fc775c16b400a41cb42b29946d1c2d4e343d0e29944e8cad12ea3a34f600d
BLAKE2b-256 checksum
How to use checksums
f67bd7f1aaa8335b081b69785234cd3dc0f693ba2074e34bdeabddf7d8b929a1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.4.2 CPython/3.11.3 Windows/10

Release files / portbt-0.1.8-py3-none-any.whl

Download URL portbt-0.1.8-py3-none-any.whl
Size 6.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
80d6993fd0cbdbdb30aa7d359f47cdbde60874d9268fbfc89546045e448bec32
BLAKE2b-256 checksum
How to use checksums
e8c48fbf41538e39ff170c7e722cb81cf0006ce43df7921fb129457038233593
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.4.2 CPython/3.11.3 Windows/10

Security for portbt 0.1.8

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page