← Back to Home
Triple Filter Trading Strategy with Long-Term Trend and Momentum Signals

Triple Filter Trading Strategy with Long-Term Trend and Momentum Signals

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.

Strategy Overview

The Triple Filter Trading Strategy incorporates the following components:

Code Implementation

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,
            period_me1=self.params.macd_fast,
            period_me2=self.params.macd_slow,
            period_signal=self.params.macd_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)
            is_uptrend = self.dataclose[0] > self.long_ema[0]

            # Condition 2: MACD line crosses above signal line
            is_buy_signal = self.macd_cross[0] > 0.0

            if is_uptrend and is_buy_signal:
                self.order = self.buy()

        # Exit logic (in position)
        else:
            # Condition: MACD line crosses below signal line
            is_sell_signal = self.macd_cross[0] < 0.0

            if is_sell_signal:
                self.order = self.close()

Strategy Explanation

1. TripleFilterStrategy

The strategy uses two key indicators to generate trade signals, focusing on long-only trades in trending markets:

Key Features

Pasted image 20250716160101.png Pasted image 20250716160106.png

Potential Improvements

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.