This article describes a trading strategy implemented in Backtrader that combines a long-term trend filter with a momentum-based entry signal to capture trades in trending markets. The strategy uses an Exponential Moving Average (EMA) for trend direction and the Moving Average Convergence Divergence (MACD) indicator for entry and exit signals, ensuring disciplined trade execution.
The Triple Filter Trading Strategy incorporates the following components:
Below is the complete Backtrader code for the strategy:
import backtrader as bt
class TripleFilterStrategy(bt.Strategy):
"""
A strategy that combines a long-term trend filter with a momentum-based entry.
1. Trend Filter: Price must be above a long-term EMA.
2. Momentum Trigger: MACD must signal a buy.
"""
= (
params 'ema_period', 200),
('macd_fast', 12),
('macd_slow', 26),
('macd_signal', 9),
(
)
def __init__(self):
# Keep a reference to the close price
self.dataclose = self.datas[0].close
self.order = None
# Trend Filter: Long-term EMA
self.long_ema = bt.indicators.ExponentialMovingAverage(
self.dataclose, period=self.params.ema_period
)
# Momentum Trigger: MACD
self.macd = bt.indicators.MACD(
self.dataclose,
=self.params.macd_fast,
period_me1=self.params.macd_slow,
period_me2=self.params.macd_signal
period_signal
)
# MACD Crossover indicator
self.macd_cross = bt.indicators.CrossOver(self.macd.macd, self.macd.signal)
def notify_order(self, order):
# Reset order reference after processing
if order.status in [order.Completed, order.Canceled, order.Margin, order.Rejected]:
self.order = None
def next(self):
# Check for pending orders
if self.order:
return
# Entry logic (no position)
if not self.position:
# Condition 1: Price above long-term EMA (uptrend)
= self.dataclose[0] > self.long_ema[0]
is_uptrend
# Condition 2: MACD line crosses above signal line
= self.macd_cross[0] > 0.0
is_buy_signal
if is_uptrend and is_buy_signal:
self.order = self.buy()
# Exit logic (in position)
else:
# Condition: MACD line crosses below signal line
= self.macd_cross[0] < 0.0
is_sell_signal
if is_sell_signal:
self.order = self.close()
The strategy uses two key indicators to generate trade signals, focusing on long-only trades in trending markets:
Indicators:
Trading Logic (next
):
notify_order
method resets the order reference after completion, cancellation, or
rejection, ensuring the strategy can place new orders.
ema_period
,
macd_fast
, macd_slow
, or
macd_signal
for specific assets or market conditions.This strategy is designed for trending markets, such as equities or indices, where long-term uptrends and momentum shifts are prevalent, and can be backtested to assess its effectiveness across different assets and timeframes.