How to Use Alternating Body Color and a Donchian-Based Range Filter to Improve Entry Timing in NinjaTrader 8

That’s where this simple but effective NinjaTrader strategy comes in. It uses alternating body candles for entry signals and filters them using a Donchian Channel-based range filter. This guide will show you exactly how it works and how to install and test it yourself.

How to Use Alternating Body Color and a Donchian-Based Range Filter to Improve Entry Timing in NinjaTrader 8

Many traders get excited when they see a green candle after a red one. Or a red after a green. But in practice, these signals often lead to bad entries — especially in sideways or low-volatility markets.

That’s where this simple but effective NinjaTrader strategy comes in. It uses alternating body candles for entry signals and filters them using a Donchian Channel-based range filter.

This guide will show you exactly how it works and how to install and test it yourself.

What This Strategy Measures

The base of this strategy is the TdjAlternatingBodyColor indicator. It identifies moments when candle body colors alternate — green after red for bullish setups, and red after green for bearish setups.

Alternating Body Color NinjaTrader 8 Indicator

But not every alternating candle is worth trading. So we add a filter using a 100-period Donchian Channel and a 5-bar EMA of candle body size. Here’s what it measures:

  • dc100Range: The high–low range of the 100-bar Donchian Channel
  • emaBodyRange: The smoothed average of recent candle body sizes
  • emaBodyRangeDcRangeRatio: The ratio of average body size vs Donchian range

We then check if:

  • The range is not too small (MinRangeTicks)
  • The range is not too big (MaxRangeTicks)
  • The body size ratio is within expected bounds (Min/MaxAverageBodyRangeDCRangeRatio)

Only if all of these are true does the strategy allow an entry.

How to Install the Strategy in NinjaTrader 8

You have two options:

✅ Option 1: Download from GitHub

Clone or download this project from the open GitHub repo:
👉 https://github.com/anatoliecatarau/TradingDJStrategyLab

See the project README for more details.

✅ Option 2: Use the ready-made ZIP

You can also download the strategy as a pre-packaged ZIP and import it directly:

Download the ZIP file:

Strategy Settings and Customization

Once imported, you’ll find the strategy under the name: TdjLabAlternatingBodyColorV1

It includes a set of configurable properties:

✳️ Entry Logic

  • Confirmation: Wait for a second same-colored candle to confirm the signal
  • EntryType: Choose between StopMarket or Market orders

📏 Range Filter Settings

  • MinRangeTicks: Minimum Donchian range to allow a trade
  • MaxRangeTicks: Maximum Donchian range
  • MinAverageBodyRangeDCRangeRatio: Minimum body-to-range ratio
  • MaxAverageBodyRangeDCRangeRatio: Maximum body-to-range ratio

🕒 Time and Exit Controls

  • StartTime, EndTime: Limit entries to a specific time window
  • CloseAtBar: Exit after a fixed number of bars
  • Target, Stop, TrailStop: Manage exits

These parameters allow you to tune how aggressive or conservative the strategy behaves.

Code Breakdown: How It Works Under the Hood

This strategy is clean and modular. Let’s quickly walk through the key parts of the code so you know what each component does.

🔧 Indicator Initialization

These are the core components:

private DonchianChannel dc100;
private Series<double> dc100Range;
private EMA emaBodyRange;
private Series<double> emaBodyRangeDcRangeRatio;
private Series<bool> rangeFilterOk;

private TdjAlternatingBodyColor alternatingBodyColor;

When the strategy loads (OnStateChange() in State.DataLoaded), we initialize them:

alternatingBodyColor = TdjAlternatingBodyColor(Confirmation);
dc100 = DonchianChannel(100);
dc100Range = new Series<double>(this);
emaBodyRange = EMA(TdjBodyRange(), 5);
emaBodyRangeDcRangeRatio = new Series<double>(this);
rangeFilterOk = new Series<bool>(this);

✅ The Custom Range Filter Logic

This filter is the gatekeeper. If the setup doesn’t pass it, no trade is allowed.

private void manageMinRangeFilter()
{
    dc100Range[0] = dc100.Upper[0] - dc100.Lower[0];
    emaBodyRangeDcRangeRatio[0] = emaBodyRange[0] / dc100Range[0];

    int donchianRangeTicks = Convert.ToInt32(dc100Range[0] / TickSize);

    rangeFilterOk[0] = emaBodyRangeDcRangeRatio[0] >= MinAverageBodyRangeDCRangeRatio 
        && emaBodyRangeDcRangeRatio[0] <= MaxAverageBodyRangeDCRangeRatio 
        && donchianRangeTicks >= MinRangeTicks 
        && donchianRangeTicks <= MaxRangeTicks;
}

It ensures:

  • Enough volatility but not too much
  • Candle body size is in proportion to market range
  • Filters out choppy or extreme market conditions

You can uncomment the Print() line to export values and analyze them in Excel:

//Print(Time[0] + ";" + emaBodyRangeDcRangeRatio[0] + ";" + donchianRangeTicks);

🎯 Entry Logic

We only consider a trade if both the alternating candle signal and the range filter are true:

private void manageEntry()
{
    if (alternatingBodyColor.SignalUp[0] 
        && rangeFilterOk[0])
    {
        manageLongEntry(High[0] + 1 * TickSize);
    }

    if (alternatingBodyColor.SignalDown[0]
        && rangeFilterOk[0])
    {
        manageShortEntry(Low[0] - 1 * TickSize);
    }
}

Entries are placed just above or below the current candle, using stop orders if selected.

Backtest & Optimize the Strategy

Before trading live, it's critical to backtest and optimize the strategy. NinjaTrader's Strategy Analyzer makes this easy.

Example Backtest using NinjaTrader's Strategy Analyzer

Here are a few ideas to explore:

  • Test different values for MinRangeTicks and MaxRangeTicks
  • Adjust MinAverageBodyRangeDCRangeRatio to find the sweet spot between filtering too much vs too little
  • Try enabling/disabling Confirmation to see how it affects performance
  • Optimize the CloseAtBar, Target, and Stop parameters

This strategy is just a starting point. Once you understand how the core logic works, you can:

  • Copy and rename the script
  • Add other filters (e.g., trend filters, volume conditions, or session time breaks)
  • Modify exits to better suit your style

We’ve structured the code cleanly so you can build on top of it.

Conclusion

Candle color alone isn’t a strong enough reason to enter a trade. But when combined with volatility filters like the Donchian range and body range ratio, it becomes much more reliable.

This strategy is simple to understand, easy to customize, and built with real logic. Whether you’re looking for a way to improve your entries or just need a solid base to build on, this script is a great starting point.

Ready to Try It?

✅ Step 1: Download the Indicators Bundle

👉 TradingDJ Indicators Bundle (Google Drive)
This includes all custom indicators required for this and other TradingDJ strategies.

✅ Step 2: Download the Strategy Source Code

👉 GitHub: TradingDJ Strategy Lab

or from the ZIP file

✅ Step 3: Import into NinjaTrader (if you import using the ZIP file)

Open NinjaTrader 8

Go to Tools > Import > NinjaScript Add-On

Select the ZIP file or compile the script manually from source

You’ll find the strategy under TdjLabAlternatingBodyColorV1 in your strategies list.