Skip to main content

A Python package for backtesting trading strategies with OHLCV data

Project description

Aroleid Simple Strategy Prototyper

A Python package for backtesting trading strategies with OHLCV data.


Table of Contents


THE INFORMATION PROVIDED IS FOR EDUCATIONAL AND INFORMATIONAL PURPOSES ONLY. IT DOES NOT CONSTITUTE FINANCIAL, INVESTMENT, OR TRADING ADVICE. TRADING INVOLVES SUBSTANTIAL RISK, AND YOU MAY LOSE MORE THAN YOUR INITIAL INVESTMENT.

THIS SOFTWARE AND ITS DOCUMENTATION PAGES (HOSTED ON ONESECONDTRADER.COM) ARE PROVIDED "AS IS," WITHOUT ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND COPYRIGHT HOLDERS ASSUME NO LIABILITY FOR ANY CLAIMS, DAMAGES, OR OTHER LIABILITIES ARISING FROM THE USE OR DISTRIBUTION OF THIS SOFTWARE OR DOCUMENTATION PAGES. USE AT YOUR OWN RISK. ONESECONDTRADER AND ITS DOCUMENTATION PAGES ARE LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE V3.0 (GPL-3.0). SEE THE GPL-3.0 FOR DETAILS.

Quickstart Guide

Load Market Data into Pandas DataFrame

If you are using the package in a Google Colab notebook, you can mount your Google Drive to access your CSV files:

from google.colab import drive
drive.mount('/content/drive')

Install the package from PyPI (using pip or poetry, use ! in Google Colab before running the pip command in a cell):

!pip install aroleid-simple-strategy-prototyper

Import the necessary packages:

import aroleid_simple_strategy_prototyper as assp
import pandas as pd

If you want to see debug messages, you can set the logging level to DEBUG (default is INFO):

import logging
logging.getLogger("aroleid_simple_strategy_prototyper").setLevel(logging.DEBUG)

Subclass the Backtester class and implement the two abstract methods (since we just want to use the load_historical_market_data() method, we can just use pass in the body of the methods that need to be implemented):

class DummyStrategy(assp.Backtester):
    def add_indicators(self) -> None:
        pass

    def strategy(self, row: pd.Series) -> None:
        pass

After instantiating the DummyStrategy class, the load_historical_market_data() method can be used to load the historical market data into a pandas DataFrame (adjust path to your CSV file and the optional symbol filter as needed):

backtester = DummyStrategy()
backtester.load_historical_market_data(
    path_to_dbcsv="/content/drive/MyDrive/csv_port/glbx-mdp3-20241202-20241205.ohlcv-1s.csv",
    symbol="MNQZ4",
)

Documentation

Core Architecture

The Aroleid Simple Strategy Prototyper is architected around a single abstract base class, Backtester, which encapsulates the entire backtesting workflow. To implement a custom strategy, users subclass Backtester and define the two required abstract methods: add_indicators() and strategy(). This design ensures that users do not need to reimplement the underlying mechanics of the backtesting engine and it enforces a clear separation between infrastructure and strategy logic.

# ...

class Backtester(abc.ABC):
    
    # ...

    @abc.abstractmethod
    def add_indicators(self) -> None:
        pass

    @abc.abstractmethod
    def strategy(self, row: pd.Series) -> None:
        pass

    # ...

Flow of Data

After the Backtester class has been subclassed by the user by implementing the two necessary abstract methods, the historical market data can be loaded into a pandas dataframe from a local CSV file (in Databento format, see Historical Market Data) via the load_historical_market_data() method (an optional symbol filter can be applied if necessary).

# ...

# Subclass Backtester abstract base class and implement the two abstract methods
class MyBacktester(Backtester):
    def add_indicators(self) -> None:
        # ...
        
    def strategy(self, row: pd.Series) -> None:
        # ...

# Instantiate the Backtester class and load historical market data
backtester = MyBacktester()
backtester.load_historical_data("path/to/csv/file.csv")

Historical Market Data

The Aroleid Simple Strategy Prototyper is designed with compatibility with the Databento historical market data formats. This does not necessarily mean that historical market data needs to be obtained from Databento, but rather that databento's schemas, dataformats, standards, and conventions are observed and data obtained from other sources is converted to the databento format before it is used within ARBE.

The backtester expects historical data to be provided in CSV format with the following columns: ts_event, rtype, open, high, low, close, volume, and symbol. To convert your existing CSV files to this format, you can use the convert_csv_to_databento_format() function from aroleid_simple_strategy_prototyper.helpers.

The backtester supports the following Databento OHLCV bar types (the numbers correspond to Databento record type integer IDs): 1-second (32), 1-minute (33), 1-hour (34), 1-day (35). These record types are used when loading historical price data for backtesting. Unconventional record types are labelled as Unknown (<rtype id>), but will not raise an error when attempting to load data.

Development

Feature Roadmap

Each feature is listed in the order in which it should be implemented, with the most significant features listed first. Each feature is assigned a number, such as #03, and a short name, such as price-feed. This number and name will be used when creating Git branches (e.g., feature/03-price-feed), or writing commit messages, so that the user can easily track what feature each change is related to.

  • #01-Github-workflow-in-README Add GitHub workflow to README.
  • #02-csv-to-pandas_df Read external CSV file in databento format into a pandas DataFrame.

Issue Tracking

Each issue is documented and addressed in the order of importance or urgency. Like features, issues are assigned a number and a short name, such as #i05-fix-timestamp-format, prepended with i to indicate that it is an issue and not a feature. This identifier will be used in Git branches (e.g., fix/i05-fix-timestamp-format), commit messages, or pull request titles to make it easy to trace which changes resolve which issues.

CI/CD Workflow (v0.1.0)

This project follows a simplified GitHub Flow for solo development:

  1. Create a feature branch from master:

    git checkout master
    git pull origin master
    git checkout -b feature/#<feature-number>-<feature-short-name>
    
  2. Make changes and commit regularly:

    git add .
    git commit -m "Feature #<feature-number>: <commit-message>"
    
  3. Verify code quality:

    ./scripts/precheck-featuremerge.sh
    
  4. Merge to master when feature is complete:

    git checkout master
    git pull origin master
    git merge feature/#<feature-number>-<feature-short-name>
    git push origin master
    
  5. Cleanup:

    git branch -d feature/#<feature-number>-<feature-short-name>
    

For bug fixes, use the same workflow but with branch naming fix/i<issue-number>-<issue-short-name> and commit message Fix #<issue-number>: <commit-message>.

Release Process

When ready to release a new version:

  1. Update version number in pyproject.toml:

    poetry version patch  # For bug fixes (0.1.0 -> 0.1.1)
    poetry version minor  # For new features (0.1.0 -> 0.2.0)
    poetry version major  # For breaking changes (0.1.0 -> 1.0.0)
    

    Then run git commit -m "Bump version: <old-version> -> <new-version>" or git commit --amend and push to remote.

  2. Build the package:

    poetry build
    
  3. Test the package locally:

    pip install dist/*.whl
    
  4. Upload to TestPyPI (optional):

    poetry config repositories.testpypi https://test.pypi.org/legacy/
    poetry publish -r testpypi
    
  5. Create a Git tag for the release:

    git tag -a v$(poetry version -s) -m "Release v$(poetry version -s)"
    git push origin v$(poetry version -s)
    
  6. Publish to PyPI:

    poetry publish
    
  7. Create a GitHub Release with release notes.

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

aroleid_simple_strategy_prototyper-0.1.1.tar.gz (18.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

File details

Details for the file aroleid_simple_strategy_prototyper-0.1.1.tar.gz.

File metadata

File hashes

Hashes for aroleid_simple_strategy_prototyper-0.1.1.tar.gz
Algorithm Hash digest
SHA256 647b90ad89283136a88432345ec850e838aafd62985b70b7c98a985859f5cb9f
MD5 c1c19a3b3893d39e0980298da7d02b38
BLAKE2b-256 dbfce33cdfd03181faaac32c7a9f9fb409dfc40ec7ec783f295a3f1c5c64ebe3

See more details on using hashes here.

File details

Details for the file aroleid_simple_strategy_prototyper-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for aroleid_simple_strategy_prototyper-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d0bf215bdeb216b3b263ed5fe14c192f1915d5689a9692e199445bbea7522b03
MD5 d8d37a21e743bbe2483e6701ed6d540d
BLAKE2b-256 bd972671ef4c690ba6c8828d6c51b85170930c5ac59dccd760864cb1c095c14b

See more details on using hashes here.

Supported by

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