Technical analysis is a cornerstone of quantitative trading, and
backtrader
provides an excellent framework for implementing
and backtesting strategies based on key technical indicators.
Visualizing these indicators alongside price action is crucial for
understanding strategy behavior and results.
In this article, we will delve into three of the most popular and
widely used indicators – Relative Strength Index (RSI),
Moving Average Convergence Divergence (MACD), and
Bollinger Bands – and demonstrate how to implement
and plot them using backtrader
.
Visualizing Indicators with backtrader
Plotting
One of backtrader
’s most powerful features is its
integrated plotting system, built on top of matplotlib
.
After running a backtest using the Cerebro
engine, a single
command (cerebro.plot()
) generates comprehensive charts
visualizing:
Crucially, standard indicators declared within your strategy are
typically plotted automatically without needing extra plotting
code within the strategy itself. backtrader
intelligently
places oscillators like RSI and MACD in separate subplots, while
overlays like Moving Averages and Bollinger Bands are drawn directly on
the main price chart.
1. Relative Strength Index (RSI)
The Relative Strength Index (RSI) is a momentum oscillator measuring the magnitude of recent price changes to evaluate overbought or oversold conditions (typically above 70 or below 30).
Implementing RSI in backtrader
:
Python
import backtrader as bt
class RSIStrategy(bt.Strategy):
params = (
('rsi_period', 14), # Period for RSI calculation
('rsi_overbought', 70),
('rsi_oversold', 30),
)
def __init__(self):
# Store the indicator reference - backtrader plots it automatically
self.rsi = bt.indicators.RelativeStrengthIndex(
self.data, period=self.params.rsi_period)
# Optional: Add horizontal lines to the RSI plot
self.rsi.plotinfo.plotyhlines = [self.params.rsi_oversold, self.params.rsi_oversold]
def next(self):
if not self.position: # Not in the market
# Potential buy signal
if self.rsi < self.params.rsi_oversold:
self.log(f'RSI OVERSOLD, BUY CREATE {self.data.close[0]:.2f}')
self.order = self.buy()
else: # In the market
# Potential sell signal
if self.rsi > self.params.rsi_overbought:
self.log(f'RSI OVERBOUGHT, SELL CREATE {self.data.close[0]:.2f}')
self.order = self.sell()
def log(self, txt, dt=None):
''' Logging function for this strategy'''
dt = dt or self.datas[0].datetime.date(0)
print(f'{dt.isoformat()} {txt}') # Print date and log message
Plotting Behavior: When plotted using
cerebro.plot()
, the RSI typically appears in its own
subplot below the main price chart. backtrader
often
automatically draws horizontal lines at the 70 and 30 levels if
detected, or you can explicitly add them using
plotinfo.plotyhlines
as shown above.
2. Moving Average Convergence Divergence (MACD)
The Moving Average Convergence Divergence (MACD) shows the relationship between two EMAs. It consists of the MACD line, a Signal line (EMA of MACD), and a Histogram (MACD - Signal). Crossovers are often used as signals.
Implementing MACD in backtrader
:
Python
import backtrader as bt
class MACDStrategy(bt.Strategy):
params = (
('fast_period', 12),
('slow_period', 26),
('signal_period', 9),
)
def __init__(self):
# Store indicator references - backtrader plots them automatically
self.macd_obj = bt.indicators.MACD(self.data,
period_me1=self.params.fast_period,
period_me2=self.params.slow_period,
period_signal=self.params.signal_period)
# Optional: Define a crossover signal indicator for cleaner logic
self.macd_crossover = bt.indicators.CrossOver(self.macd_obj.macd, self.macd_obj.signal)
def next(self):
if not self.position:
# Buy signal: MACD line crosses above Signal line
if self.macd_crossover > 0: # Value is 1 for upward crossover
self.log(f'MACD Crossover BUY, {self.data.close[0]:.2f}')
self.order = self.buy()
else:
# Sell signal: MACD line crosses below Signal line
if self.macd_crossover < 0: # Value is -1 for downward crossover
self.log(f'MACD Crossover SELL, {self.data.close[0]:.2f}')
self.order = self.sell()
def log(self, txt, dt=None):
dt = dt or self.datas[0].datetime.date(0)
print(f'{dt.isoformat()} {txt}')
Plotting Behavior: In backtrader
plots,
the MACD line, signal line, and histogram are usually displayed together
in a separate subplot beneath the price data, making it easy to
visualize crossovers and histogram divergence.
3. Bollinger Bands
Bollinger Bands® consist of an SMA (middle band) and two outer bands plotted at +/- standard deviations. They help visualize volatility and potential price extremes relative to the recent trend.
Implementing Bollinger Bands in
backtrader
:
Python
import backtrader as bt
class BollingerBandsStrategy(bt.Strategy):
params = (
('period', 20), # Period for the SMA middle band
('devfactor', 2.0) # Standard Deviations for upper/lower bands
)
def __init__(self):
# Store indicator reference - backtrader plots it automatically
self.bbands = bt.indicators.BollingerBands(
self.data, period=self.params.period, devfactor=self.params.devfactor)
# Optional: Store individual lines if needed for complex logic
# self.mid_band = self.bbands.mid
# self.top_band = self.bbands.top
# self.bot_band = self.bbands.bot
def next(self):
if not self.position:
# Buy signal: Price closes below the lower band
if self.data.close[0] < self.bbands.lines.bot[0]:
self.log(f'BBands Low, BUY CREATE {self.data.close[0]:.2f}')
self.order = self.buy()
else:
# Sell signal: Price closes above the upper band
if self.data.close[0] > self.bbands.lines.top[0]:
self.log(f'BBands High, SELL CREATE {self.data.close[0]:.2f}')
self.order = self.sell()
# Alternative Exit: Close crosses back below middle band (example)
# elif self.data.close[0] < self.bbands.lines.mid[0]:
# self.log(f'BBands Mid Cross, SELL CREATE {self.data.close[0]:.2f}')
# self.order = self.sell()
def log(self, txt, dt=None):
dt = dt or self.datas[0].datetime.date(0)
print(f'{dt.isoformat()} {txt}')
Important Considerations:
This article provides a basic overview of implementing RSI, MACD, and
Bollinger Bands within the backtrader
framework. By
mastering these fundamental indicators, you can build a solid foundation
for developing and backtesting more complex algorithmic trading
strategies.
Further Exploration:
For a deeper dive into technical analysis and quantitative trading
with backtrader
, I recommend exploring:
backtrader
and technical analysis.Remember, consistent learning and practice are key to becoming a successful quantitative trader.
Disclaimer: This information is for educational purposes only and should not be considered financial advice. Investing in financial markets carries significant risks, and you could lose all of your invested capital.