Skip to main content

plutus is a python package for backtesting investment decisions using Python 3.6 and above.

Project description

plutus_backtest

PyPI PyPI - Python Version Downloads

Description:

This project has been performed for the purpose of local backtests of financial strategies. The package contains various indicators and tools allowing users obtaining exact results of their strategies over a certain period of time. The users are also able to pick endless amount of trading instruments and set criteria such as long or short positioning. Beside that optional stop loss and take profit signals are available not only as general limit level for entire portfolio but can be also applied for each instrument individually. Another optional tool available is weights factor distribution which is oriented to assign weights according to the provided values. In addition, the package allows to create full html report containing varius graphs and indicators.


Tickers for analysis are available on Yahoo Finance page.

Installation:

  • Dependency: pandas, numpy, plotly, yfinance, dash, tabulate
  • Install from pypi:
pip install plutus_backtest
  • Verified in Python:
from plutus.backtest import execution

Examples:

Function "execution" contains below parameters:

asset: str or list or series
   Instruments taken into the consideration for the backtest.
o_day: list of str or timestamps or series
   Day/Days of the position opening.
c_day: list of str or timestamps or series
   Day/Days of the position closing.
weights_factor: list of int or float or array-like or series default None
   Optional list of factors which will be considered to define the weights for taken companies. By default
   all weights are distributed equally, however if the list of factors provided the backtest will maximize
   the weights towards the one with max weight factor. Negative weight factor will be considered as short selling.
take_profit: list of float or int or series default None
   List of values determining the level till a particular stock shall be traded.
stop_loss: list of float or int or series default None
   List of values determining the level till a particular stock shall be traded.
benchmark: str default None
   A benchmark ticker for comparison with portfolio performance
price_period_relation: str default 'O-C'
   Instruct what part of the trading day a position shall be opened,
   and what part of trading day it shall be closed.
   Possible relations:
   O-C / Open to Close prices
   C-O / Close to Open prices
   C-C / Close to Close prices
   O-O / Open to Open prices
   "Open" - the price at which a security first trades upon the opening of an exchange on a trading day.
   "Close" - value of the last transacted price in a security before the market officially closes.
full_report: bool, optional, default False
   Generates full report in your browser.
major_sample: int or None, optional, default 10
   Based on duration of the trading period as well as weights factor of the asset.
   In order to make understandable visualisation in full report graphs such as weights changes and
   weights distribution, major sample is used which will focus to provide info regarding main provided
   assets. Can be changed to any int. If value is None the backtest will consider all assets as major
   ones.

A short and fast way to run a single backtest would be:


from plutus.backtest import execution

bt = execution(asset=["AAPL", "BTC-USD", "GC=F"], o_day=["2021-08-01", "2021-08-03", "2021-09-05"],
               c_day=["2021-09-01", "2021-10-04", "2022-03-12"])

As a result a statistical table as well as graphical representation of the portfolio accumulated return will appear.


1


In order to access dataframe with portfolio daily changes and weights distribution, use:


from plutus.backtest import execution

bt, portfolio_daily_changes, portfolio_weights = execution(asset=["AAPL", "TWTR", "GC=F"], 
                                                  o_day=["2021-08-01", "2021-08-03", "2021-09-05"],
                                                  c_day=["2021-09-01", "2021-10-04", "2022-03-12"])

portfolio_daily_changes.head()

The result will appear as following (all values are in %):


port fin head


If the user would like to compare performance of of the portfolio with any other instrument a parameter "benchmark" shall be called:


from plutus.backtest import execution

bt = execution(asset=["AAPL", "TWTR", "FB"], o_day=["2021-08-01", "2021-08-03", "2021-09-05"],
               c_day=["2021-09-01", "2021-10-04", "2022-03-12"], benchmark= ['^GSPC'])

Above example will additionaly plot a S&P 500 index performance (accumulated return from same period as the portfolio) [grey line] on the accumulated graph:


2


"Full report" is an optional parameter which allows users users to observe additional graphs frames and indicators:


from plutus.backtest import execution

bt = execution(asset=["AAPL", "F", "MS"], 
              o_day=["2020-08-01", "2020-07-15", "2020-08-20"],
              c_day=["2021-09-01", "2021-09-01", "2021-09-15"], full_report = True)

Above script will generate a link to Dash app with report:


image


By clicking it, and it will redirect to a new tab.


127 0 0 1_8050_ (6)


If the user didn't specify weights of particular assets in the portfolio (using weights_factor parameter), % allocation will be distributed equally (in selected period of time) and shown in the last plot called Weights rebalancing.


127 0 0 1_8050_ (7)


from plutus.backtest import execution

bt = execution(asset=["AAPL", "F", "MS"],
              o_day=["2020-08-01", "2020-07-15", "2020-08-20"],
              c_day=["2021-09-01", "2021-09-01", "2021-09-15"],
              weights_factor = [50, 40, 10], full_report = True)

In case of specifying % of portfolio allocation for each asset (AAPL = 50%, F = 40%, MS = 10% from above example) above plots will be adjusted. Example of Weights distribution plot:


127 0 0 1_8050_ (8)


No need to include weights that will sum up to 100% (but it is recommended). Code calculates % based on value / total of absolute values. For example:


from plutus.backtest import execution

bt = execution(asset=["AAPL", "F", "MS"],
              o_day=["2020-08-01", "2020-07-15", "2020-08-20"],
              c_day=["2021-09-01", "2021-09-01", "2021-09-15"],
              weights_factor = [35, 140, -21], full_report = True)

weights_factor total is 196 [35 + 140 + 21].
AAPL: 35 / 196 = ~17%
F: 140 / 196 = ~71.4%
MS: |21| / 196 = ~10.7%

Keep in mind that weights factor with "-" sign will indicate short selling for a particular asset


127 0 0 1_8050_ (9)


More complex approach would be assigning weights factor/stop loss/ take profit indicators:


from plutus.backtest import execution

bt = execution(asset = ["AAPL", "BTC-USD","GC=F"], 
              o_day = ["2021-08-01", "2021-07-15", "2021-08-20"],
              c_day = ["2021-09-01", "2021-09-01","2021-09-15"], 
              weights_factor = [10, -5, 35], 
              stop_loss = [0.8, 0.9, 0.95], 
              take_profit = [1.1, 1.2, 1.05], full_report = True)

In this case the weights will not be distributed equally. "AAPL" will have 20% of the total portofolio BTC-USD - 10% and "GC=F" will have 70%. The negative sign in the weights factor will mean short selling, therefore first "AAPL" and "GC=F" instruments are in long position and "BTC-USD" is in the short.


Stop loss and take profit shall be interpreted as "AAPL" has 20% of stop loss and 10% of take profit, "BTC-USD" has 10% of stop loss and 20% of take profit, "GC=F" 5% of stop loss and 5% of take profit. As result accumulative graph will look as:


127 0 0 1_8050_ (10)


In the moment when one of the securities reaching its stop loss or take profit, the trade will be automatically stopped and the weights will be reassigned respectively to the left assets.


In case of users need to test one instrument but several times with different timelines, the package will interpret it as:


from plutus.backtest import execution

bt, portfolio_daily_changes, pprtfolio_weights = execution(asset = ["AMZN", "AMZN","AMZN"], 
              o_day = ["2021-08-01", "2021-09-01", "2021-10-01"],
              c_day = ["2021-08-15", "2021-09-15","2021-10-15"])

multiindex


Each time when one asset is repeating the backtest will unite it under one comon ticker name, the same corrections will happen on the graphs. It's worth to mention that due to data limitation the code uses close price for the analysis of the securities.


Support:

Please open an issue for support.
With additional questions please reachout to autors directly:

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lopata-0.3.3.tar.gz (18.9 kB view details)

Uploaded Source

File details

Details for the file lopata-0.3.3.tar.gz.

File metadata

  • Download URL: lopata-0.3.3.tar.gz
  • Upload date:
  • Size: 18.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.8.2 pkginfo/1.8.1 requests/2.28.1 requests-toolbelt/0.9.1 tqdm/4.62.2 CPython/3.9.7

File hashes

Hashes for lopata-0.3.3.tar.gz
Algorithm Hash digest
SHA256 94de9ac13e40d4d6b8269e4198db8e6403a3dc6a2649caf160e97cb7d5de54df
MD5 99c43237625cb11fd97b3b2629f0cad0
BLAKE2b-256 896c3856be30cbcf31f75b798f3a570383d0d0ab6182f1dea6fbe2246033cd48

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page