Skip to main content

stock-backtest

PyPI License: MIT codecov Build Status PyPI - Python Version Downloads

stock-backtest is a python library for stock technical analysis backtest on Python 3.7 and above.

Installation

$ pip install stock-backtest

Usage

basic run

from stock_backtest import Backtest

class MyBacktest(Backtest):
    def strategy(self):
        fast_ma = self.sma(period=5)
        slow_ma = self.sma(period=25)
        # golden cross
        self.sell_exit = self.buy_entry = (fast_ma > slow_ma) & (
            fast_ma.shift() <= slow_ma.shift()
        )
        # dead cross
        self.buy_exit = self.sell_entry = (fast_ma < slow_ma) & (
            fast_ma.shift() >= slow_ma.shift()
        )

MyBacktest("AAPL").run()

AAPL--.png

advanced run

from stock_backtest import Backtest
from pprint import pprint

class MyBacktest(Backtest):
    def strategy(self):
        rsi = self.rsi(period=10)
        ema = self.ema(period=20)
        atr = self.atr(period=20)
        lower = ema - atr
        upper = ema + atr
        self.buy_entry = (rsi < 30) & (self.df.C < lower)
        self.sell_entry = (rsi > 70) & (self.df.C > upper)
        self.sell_exit = ema > self.df.C
        self.buy_exit = ema < self.df.C

bt = MyBacktest(
    "AAPL",  # ticker
    shares=100,  # number of shares (default=1)
    start="2010-01-01",  # start date (default="")
    end="2020-01-01",  # end date (default="")
    data_dir="data",  # data directory (default=.)
)
pprint(bt.run(), sort_dicts=False)
{'total profit': -2779.465,
 'total trades': 102,
 'win rate': 66.667,
 'profit factor': 0.641,
 'maximum drawdown': 3147.5,
 'recovery factor': -0.883,
 'riskreward ratio': 0.321,
 'sharpe ratio': -0.085,
 'average return': -68.929,
 'stop loss': 0,
 'take profit': 0}

AAPL-2010-01-01-2020-01-01.png

Supported indicators

  • Simple Moving Average 'sma'
  • Exponential Moving Average 'ema'
  • Moving Average Convergence Divergence 'macd'
  • Relative Strenght Index 'rsi'
  • Bollinger Bands 'bbands'
  • Stochastic Oscillator 'stoch'
  • Average True Range 'atr'

Strategy examples

MACD

class MyBacktest(Backtest):
    def strategy(self):
        macd, signal = self.macd(fast_period=12, slow_period=26, signal_period=9)
        self.sell_exit = self.buy_entry = (macd > signal) & (
            macd.shift() <= signal.shift()
        )
        self.buy_exit = self.sell_entry = (macd < signal) & (
            macd.shift() >= signal.shift()
        )

Bollinger Bands

class MyBacktest(Backtest):
    def strategy(self):
        upper, mid, lower = self.bbands(period=20, band=2)
        self.sell_exit = self.buy_entry = (upper > self.df.C) & (
            upper.shift() <= self.df.C.shift()
        )
        self.buy_exit = self.sell_entry = (lower < self.df.C) & (
            lower.shift() >= self.df.C.shift()
        )

Stochastic

class MyBacktest(Backtest):
    def strategy(self):
        k, d = self.stoch(k_period=5, d_period=3)
        self.sell_exit = self.buy_entry = (
            (k > 20) & (d > 20) & (k.shift() <= 20) & (d.shift() <= 20)
        )
        self.buy_exit = self.sell_entry = (
            (k < 80) & (d < 80) & (k.shift() >= 80) & (d.shift() >= 80)
        )

Moving average divergence rate

class MyBacktest(Backtest):
    def strategy(self):
        sma = self.sma(period=20)
        ratio = (self.df.C - sma) / sma * 100
        self.sell_exit = self.buy_entry = ratio > -5 & (ratio.shift() <= -5)
        self.buy_exit = self.sell_entry = ratio < 5 & (ratio.shift() >= 5)

Momentum

class MyBacktest(Backtest):
    def strategy(self):
        mom = self.df.C - self.df.C.shift(10)
        self.sell_exit = self.buy_entry = mom > 0 & (mom.shift() <= 0)
        self.buy_exit = self.sell_entry = mom < 0 & (mom.shift() >= 0)

Donchian Channels

class MyBacktest(Backtest):
    def strategy(self):
        high = self.df.H.rolling(20).max()
        low = self.df.L.rolling(20).min()
        self.sell_exit = self.buy_entry = (high > self.df.C) & (
            high.shift() <= self.df.C
        )
        self.buy_exit = self.sell_entry = (low < self.df.C) & (
            low.shift() >= self.df.C
        )

Relative Vigor Index

class MyBacktest(Backtest):
    def rvi(
        self, *, period: int = 10, price: str = "C"
    ) -> Tuple[pd.DataFrame, pd.DataFrame]:
        co = self.df.C - self.df.O
        n = (co + 2 * co.shift(1) + 2 * co.shift(2) + co.shift(3)) / 6
        hl = self.df.H - self.df.L
        d = (hl + 2 * hl.shift(1) + 2 * hl.shift(2) + hl.shift(3)) / 6
        rvi = n.rolling(period).mean() / d.rolling(period).mean()
        signal = (rvi + 2 * rvi.shift(1) + 2 * rvi.shift(2) + rvi.shift(3)) / 6
        return rvi, signal

    def strategy(self):
        rvi, signal = self.rvi(period=5)
        self.sell_exit = self.buy_entry = (rvi > signal) & (
            rvi.shift() <= signal.shift()
        )
        self.buy_exit = self.sell_entry = (rvi < signal) & (
            rvi.shift() >= signal.shift()
        )

Metadata

Release files for stock-backtest 0.1.1

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

Source distribution (sdist)

Source distribution for stock-backtest 0.1.1
File Size Uploaded
stock-backtest-0.1.1.tar.gz 7.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for stock-backtest 0.1.1
File Interpreter ABI Platform
stock_backtest-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 13.1 kB

Release files / stock-backtest-0.1.1.tar.gz

Download URL stock-backtest-0.1.1.tar.gz
Size 7.1 kB
Tags Source
SHA-256 checksum
How to use checksums
abdbf8b64cc3b78798e92a0431264e3fa57d0200c38d4c1222d4c20fbfd658be
BLAKE2b-256 checksum
How to use checksums
6ea00656a39548977e02984a4cc24120fb3e091adada118743e75d82951080ee
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.1 importlib_metadata/4.0.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.8.2

Release files / stock_backtest-0.1.1-py3-none-any.whl

Download URL stock_backtest-0.1.1-py3-none-any.whl
Size 6.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1062d6a116aa2baf2ed0e83bad16e18890cda6d792edd7af8c89918d2caa8a40
BLAKE2b-256 checksum
How to use checksums
91b99fd9bb25b786a1ed7b1a9780551cf605705c6351eae7279eef70c4a10101
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.1 importlib_metadata/4.0.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.8.2

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

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