Backtesting

lucit-backtesting - 'backtesting.py' maintained by LUCIT

GitHub Release PyPi Release Supported Python Version License PyPi Downloads PyPi Downloads PyPi Downloads PyPI - Status CodeQL Read the Docs Github Telegram Get Free Professional Support GitHub Sponsors

Backtest trading strategies with Python.

Kudos to Zach Lûster for the original project kernc/backtesting.py which he built and maintained for 5 years.

We at LUCIT like to use backtesting.py with our customers in smaller projects. Unfortunately the project is missing important updates, and therefore we decided to fork the project and release new stable versions.

We are happy to maintain our forked repository and take care of code reviews, pull requests and releases and hope for good support from the community!

Description

The package lucit-backtesting is a Python framework for inferring viability of trading strategies on historical (past) data. Of course, past performance is not indicative of future results, but a strategy that proves itself resilient in a multitude of market conditions can, with a little luck, remain just as reliable in the future. Improved upon the vision of Backtrader, and by all means surpassingly comparable to other accessible alternatives, Backtesting.py is lightweight, fast, user-friendly, intuitive, interactive, intelligent and, hopefully, future-proof. It is also documented well, including a handful of tutorials.

Feature Description
Compatible with forex, crypto, stocks, futures ... Backtest any financial instrument for which you have access to historical candlestick data.
Blazing fast, convenient Built on top of cutting-edge ecosystem libraries (i.e. Pandas, NumPy, Bokeh) for maximum usability.
Small, clean API The API reference is easy to wrap your head around and fits on a single page.
Technical indicator library agnostic Compatible with any sensible technical analysis library, such as TA-Lib or Tulip.
Built-in optimizer Test hundreds of strategy variants in mere seconds, resulting in heatmaps you can interpret at a glance.
High-level API Think market timing, swing trading, money management, stop-loss and take-profit prices, leverage, machine learning ...
Interactive visualization Simulated trading results in telling interactive charts you can zoom into. See Example.
Vectorized or event-based backtesting Signal-driven or streaming, model your strategy enjoying the flexibility of both approaches.
Composable strategies Contains a library of predefined utilities and general-purpose strategies that are made to stack.

Installation

You can have either backtesting.py or lucit-backtesting installed, but not both!

$ pip uninstall backtesting
$ pip install lucit-backtesting

Usage

The example shows a simple, unoptimized moving average cross-over strategy. It's a common introductory strategy and a pretty decent strategy overall, provided the market isn't whipsawing sideways.

We begin with 10,000 units of currency in cash, realistic 0.2% broker commission, and we trade through 9 years worth of Alphabet Inc. stock.

Whenever the fast, 10-period simple moving average of closing prices crosses above the slower, 20-period moving average, we go long, buying as many stocks as we can afford. When it crosses below, we close our long position and go short (assuming the underlying instrument is actually a CFD and can be shorted).

We record most significant statistics this simple system produces on our data, and we show a plot for further manual inspection.

from backtesting import Backtest, Strategy
from backtesting.lib import crossover
from backtesting.test import SMA, GOOG

class SmaCross(Strategy):
    def init(self):
        price = self.data.Close
        self.ma1 = self.I(SMA, price, 10)
        self.ma2 = self.I(SMA, price, 20)

def next(self):
    if crossover(self.ma1, self.ma2):
        self.buy()
    elif crossover(self.ma2, self.ma1):
        self.sell()

bt = Backtest(GOOG, SmaCross, commission=0.002, exclusive_orders=True)
stats = bt.run()
bt.plot()
print(f"\r\nOverview:\r\n{stats}\r\n")
print(f"\r\nEquity:\r\n{stats['_equity_curve']}\r\n")
print(f"\r\nTrades:\r\n{stats['_trades']}")

Results in:

Overview:
Start                     2004-08-19 00:00:00
End                       2013-03-01 00:00:00
Duration                   3116 days 00:00:00
Exposure Time [%]                       94.27
Equity Final [$]                     68935.12
Equity Peak [$]                      68991.22
Return [%]                             589.35
Buy & Hold Return [%]                  703.46
Return (Ann.) [%]                       25.42
Volatility (Ann.) [%]                   38.43
Sharpe Ratio                             0.66
Sortino Ratio                            1.30
Calmar Ratio                             0.77
Max. Drawdown [%]                      -33.08
Avg. Drawdown [%]                       -5.58
Max. Drawdown Duration      688 days 00:00:00
Avg. Drawdown Duration       41 days 00:00:00

# Trades                                   93
Win Rate [%]                            53.76
Best Trade [%]                          57.12
Worst Trade [%]                        -16.63
Avg. Trade [%]                           1.96
Max. Trade Duration         121 days 00:00:00
Avg. Trade Duration          32 days 00:00:00
Profit Factor                            2.13
Expectancy [%]                           6.91
SQN                                      1.78
Kelly Criterion                        0.6134
_strategy              SmaCross(n1=10, n2=20)
_equity_curve                          Equ...
_trades                       Size  EntryB...
dtype: object

Equity:
                          Equity  DrawdownPct DrawdownDuration
Date
2023-01-02 13:03:00  10000.00000     0.000000              NaT
2023-01-02 13:04:00  10000.00000     0.000000              NaT
2023-01-02 13:05:00  10000.00000     0.000000              NaT
2023-01-02 13:06:00  10000.00000     0.000000              NaT
2023-01-02 13:07:00  10000.00000     0.000000              NaT
...                          ...          ...              ...
2024-01-01 00:55:00  11585.32229     0.050322              NaT
2024-01-01 00:56:00  11585.32229     0.050322              NaT
2024-01-01 00:57:00  11585.32229     0.050322              NaT
2024-01-01 00:58:00  11585.32229     0.050322              NaT
2024-01-01 00:59:00  11585.32229     0.050322 51 days 18:57:00

Trades:
    Size  EntryBar  ExitBar  EntryPrice    ExitPrice         PnL  ReturnPct           EntryTime            ExitTime   Tag        Duration
0      6     23305    23305  1524.62018  1517.480252  -42.839567  -0.004683 2023-01-18 17:28:00 2023-01-18 17:28:00  None 0 days 00:00:00
1      6     23308    23568  1522.60415  1521.180000   -8.544900  -0.000935 2023-01-18 17:31:00 2023-01-18 21:51:00  None 0 days 04:20:00
2      6     23569    32957  1525.95417  1543.780000  106.954980   0.011682 2023-01-18 21:52:00 2023-01-25 10:20:00  None 6 days 12:28:00
3      6     32958    40820  1546.69621  1542.810000  -23.317260  -0.002513 2023-01-25 10:21:00 2023-01-30 21:23:00  None 5 days 11:02:00
4      6     40821    43959  1550.01614  1690.310000  841.763160   0.090511 2023-01-30 21:24:00 2023-02-02 01:42:00  None 2 days 04:18:00
..   ...       ...      ...         ...          ...         ...        ...                 ...                 ...   ...             ...
78     5    488520   488665  2205.67724  2184.630000 -105.236200  -0.009542 2023-12-11 19:03:00 2023-12-11 21:28:00  None 0 days 02:25:00
79     5    488666   488673  2192.94917  2185.350000  -37.995850  -0.003465 2023-12-11 21:29:00 2023-12-11 21:36:00  None 0 days 00:07:00
80     5    488674   489911  2191.03344  2187.110000  -19.617200  -0.001791 2023-12-11 21:37:00 2023-12-12 18:14:00  None 0 days 20:37:00
81     5    489912   503782  2188.65633  2305.250000  582.968350   0.053272 2023-12-12 18:15:00 2023-12-22 09:25:00  None 9 days 15:10:00
82     5    514701   517609  2277.31150  2259.124026  -90.937372  -0.007986 2023-12-29 23:24:00 2023-12-31 23:52:00  None 2 days 00:28:00

Bugs

Before reporting bugs or posting to the discussion board and please read contributing guidelines. We thank you!

Do you have any questions? We will be happy to answer them in our chat - usually you will receive an answer within a few minutes during our opening hours.

Arrange a free & no obligation consultation

Together we will clarify your needs and you will receive a detailed offer

Make an appointment now