Quantified Trader

How to Backtest a Bollinger Band Strategy using Pyfolio in Python

This article aims to provide a step-by-step guide to conducting a backtest for a strategy based on technical indicators using Python. We will focus on implementing a Bollinger Band based strategy to generate signals and positions.

There are various alternatives to this code, but we will be adopting a vectorized backtesting approach using the pandas framework.

Read more such Articles :- How to Build an Indian Stock Market Prediction App Using Prophet

Bollinger Band Reversal Strategy

The Bollinger Band strategy we’ll employ involves the following steps:

  • Generating Bollinger Bands with a 20-day window, allowing for variations within plus or minus 2 standard deviations, based on the adjusted closing price.
  • Buying when the price rises above the lower band from above and maintaining the position until the price surpasses the upper band from below on the subsequent occasion.
  • Selling when the price crosses below the upper band from below and retaining the position until the price crosses above the lower band from the top in the next instance.

How to Backtest Bollinger Band Reversal Strategy

Here are the steps to create your own back-testing code:

Step 1: Import Necessary Libraries

To get started, import the essential libraries:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import yfinance as yf
import pyfolio as pf
import warnings
warnings.filterwarnings('ignore')  # Ignore printing all warnings

# Print all outputs
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

Step 2: Download OHLCV Data

To gather historical data for analysis, we utilize the Yahoo Finance Python API (yfinance). Alternatively, you can use various open and free resources for historical data.

# Downloading historical data for backtesting and analysis
start_date ='2015-01-01'
end_date = '2020-12-31'
ticker = '^NSEI'
df = yf.download(tickers=ticker, start=start_date, end=end_date)

Also Read:- How to use Pairs Trading Strategy for Swing Trading

Step 3: Calculate Daily Returns

Calculate daily returns to assess the strategy’s performance compared to a buy-and-hold strategy:

# Calculating buy and hold strategy returns
df['buy_and_hold_returns'] = np.log(df['Adj Close'] / df['Adj Close'].shift(1))
df.head(3)

Step 4: Create Strategy-Based Data Columns

Backtest Bollinger Bands in Python

Develop indicators specific to the strategy, such as moving averages and Bollinger Bands:

# Creating Bollinger Band indicators
df['MA_20days'] = df['Adj Close'].rolling(window=20).mean()
df['std'] = df['Adj Close'].rolling(window=20).std()
df['upper_band'] = df['MA_20days'] + (2 * df['std'])
df['lower_band'] = df['MA_20days'] - (2 * df['std'])
df.drop(['Open', 'High', 'Low', 'Close'], axis=1, inplace=True, errors='ignore')
df.tail(5)

Step 5: Create Strategy Indicators

Generate long and short signals and positions according to the Bollinger Band strategy:

# Long condition
df['signal'] = 0
df['signal'] = np.where((df['Adj Close'] < df['lower_band']) &
                        (df['Adj Close'].shift(1) >= df['lower_band']), 1, 0)

# Short condition
df['signal'] = np.where((df['Adj Close'] > df['upper_band']) &
                        (df['Adj Close'].shift(1) <= df['upper_band']), -1, df['signal'])

# Creating long and short positions
df['position'] = df['signal'].replace(to_replace=0, method='ffill')
df['position'] = df['position'].shift(1)

# Calculating strategy returns
df['strategy_returns'] = df['buy_and_hold_returns'] * (df['position'])

df.tail(5)

df['signal'].value_counts()
Backtest Bollinger Bands in Python

Step 6: Analyze Results

In this stage, utilize Pyfolio, a Python library designed for portfolio performance and risk assessment:

pf.create_simple_tear_sheet(df['strategy_returns'].diff())

Results

Backtest Bollinger Bands in Python
Backtest Bollinger Bands in Python

The results obtained through Pyfolio offer a clear and comprehensive overview of the findings.

In the analysis of historical data, it becomes evident that the ‘Bollinger Band strategy does not outperform the straightforward buy-and-hold approach. To illustrate, the cumulative daily returns for the buy and hold strategy reached 1.44 times the initial investment, while the Bollinger band strategy only yielded returns amounting to 0.37 times the initial investment.

However, it is crucial to exercise caution when considering the transition from back-testing to live implementation, even if the former suggests promising returns. Several factors, including transaction costs and stock price momentum, can introduce unforeseen risks.

To enhance a strategy’s performance, explore optimization opportunities by assessing returns associated with various strategy parameters. Additionally, combining different technical indicators can generate more reliable signals, mitigating risks and improving overall performance.

For live strategies, implement safeguards such as stop-loss mechanisms and kill switches to maintain control in case the strategy deviates from its intended course. These precautions are vital for safeguarding investments and minimizing potential losses.

For more such strategies follow me at Github\QuantifiedTrader

Conclusion

Back-testing is a critical step in evaluating the viability of a trading strategy, and Python, along with Pyfolio, offers robust tools for this purpose. Understanding and analyzing the results obtained from back-testing is essential for making informed investment decisions.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top