NinjaTrader MACD Strategy workflow

NinjaTrader MACD crossover strategy with editable NinjaScript

This example evaluates MACD signal-line crossovers at bar close, with an optional zero-line filter for both directions. Review its editable NinjaTrader 8 source, order rules, and data assumptions before testing.

Managed NinjaScript MACD Crossover Strategy

A complete single-file NinjaTrader 8 Strategy featuring MACD signal line crossover detection, optional positive zero-line trend filtering, and managed tick brackets.

using System;
using System.ComponentModel.DataAnnotations;
using NinjaTrader.Cbi;
using NinjaTrader.NinjaScript;
using NinjaTrader.NinjaScript.Indicators;

namespace NinjaTrader.NinjaScript.Strategies
{
    public class MacdCrossoverStrategy : Strategy
    {
        [NinjaScriptProperty]
        [Range(1, 100)]
        [Display(Name = "Fast Period", GroupName = "Parameters", Order = 0)]
        public int FastPeriod { get; set; }

        [NinjaScriptProperty]
        [Range(2, 200)]
        [Display(Name = "Slow Period", GroupName = "Parameters", Order = 1)]
        public int SlowPeriod { get; set; }

        [NinjaScriptProperty]
        [Range(1, 100)]
        [Display(Name = "Smooth Period", GroupName = "Parameters", Order = 2)]
        public int SmoothPeriod { get; set; }

        [NinjaScriptProperty]
        [Display(Name = "Require Positive MACD for Longs", GroupName = "Filters", Order = 3)]
        public bool RequirePositiveMacd { get; set; }

        [NinjaScriptProperty]
        [Range(1, 200)]
        [Display(Name = "Profit Target (Ticks)", GroupName = "Risk", Order = 4)]
        public int TargetTicks { get; set; }

        [NinjaScriptProperty]
        [Range(1, 200)]
        [Display(Name = "Stop Loss (Ticks)", GroupName = "Risk", Order = 5)]
        public int StopLossTicks { get; set; }

        private MACD macd;

        protected override void OnStateChange()
        {
            if (State == State.SetDefaults)
            {
                Name = "MacdCrossoverStrategy";
                Description = "MACD signal line crossover strategy with optional zero-line filter.";
                Calculate = Calculate.OnBarClose;
                EntriesPerDirection = 1;
                EntryHandling = EntryHandling.AllEntries;
                IsExitOnSessionCloseStrategy = true;
                ExitOnSessionCloseSeconds = 30;

                FastPeriod = 12;
                SlowPeriod = 26;
                SmoothPeriod = 9;
                RequirePositiveMacd = false;
                TargetTicks = 20;
                StopLossTicks = 15;
            }
            else if (State == State.DataLoaded)
            {
                macd = MACD(FastPeriod, SlowPeriod, SmoothPeriod);

                SetProfitTarget("MacdLong", CalculationMode.Ticks, TargetTicks);
                SetStopLoss("MacdLong", CalculationMode.Ticks, StopLossTicks, false);

                SetProfitTarget("MacdShort", CalculationMode.Ticks, TargetTicks);
                SetStopLoss("MacdShort", CalculationMode.Ticks, StopLossTicks, false);
            }
        }

        protected override void OnBarUpdate()
        {
            if (CurrentBar < Math.Max(FastPeriod, SlowPeriod) + SmoothPeriod)
                return;

            bool macdCrossAbove = CrossAbove(macd, macd.Avg, 1);
            bool macdCrossBelow = CrossBelow(macd, macd.Avg, 1);

            if (Position.MarketPosition == MarketPosition.Flat)
            {
                if (macdCrossAbove && (!RequirePositiveMacd || macd[0] > 0))
                {
                    EnterLong("MacdLong");
                }
                else if (macdCrossBelow && (!RequirePositiveMacd || macd[0] < 0))
                {
                    EnterShort("MacdShort");
                }
            }
        }
    }
}

Direct answer

A NinjaTrader MACD crossover strategy generates trade signals when the MACD line crosses its signal line (Avg). Traders often filter long trades by requiring the MACD line to be positive (above zero) to trade in the direction of the broader trend. In NinjaTrader 8, you can create this strategy using the visual Strategy Builder or write custom C# code. Pineify provides an inspectable single-file Strategy artifact ready for compilation and Strategy Analyzer testing.

What to know first

  • The standard MACD configuration uses 12 fast, 26 slow, and 9 smoothing periods.
  • NinjaTrader MACD indicator exposes two key plot series: the default MACD series and Avg (signal line).
  • The optional zero-line filter requires MACD > 0 for longs and MACD < 0 for shorts; it does not establish fewer losses.
  • Strategy Builder can build basic MACD rules visually, while NinjaScript C# provides finer order control and custom risk handling.
  • Validate the strategy in Strategy Analyzer with historical data before considering live or funded accounts.

Supported scope

What this NinjaScript workflow can cover

  • Single-file NinjaScript MACD strategy example
  • CrossAbove and CrossBelow signal line logic
  • Optional positive zero-line trend filter
  • Configurable tick-based profit target and stop loss
  • Native compile and historical-test workflow

How MACD crossovers work in NinjaTrader 8

The Moving Average Convergence Divergence (MACD) indicator calculates the difference between a fast exponential moving average (typically 12 periods) and a slow exponential moving average (typically 26 periods). A 9-period EMA of this difference forms the signal line (Avg).

When the fast MACD line crosses above the signal line, it signals expanding upward momentum. Conversely, when the MACD line crosses below the signal line, it signals downward momentum. In NinjaScript, the CrossAbove and CrossBelow methods provide clean, one-line evaluations of these crossover events.

  • MACD line: macd[0] = EMA(Fast) - EMA(Slow)
  • Signal line: macd.Avg[0] = EMA of MACD line over SmoothPeriod
  • Crossover test: CrossAbove(macd, macd.Avg, 1)

Strategy Builder vs writing custom NinjaScript code

NinjaTrader Strategy Builder allows traders to construct a MACD strategy without writing code by defining condition sets in a wizard interface. This works well for simple crossover triggers and basic trailing stop attachments.

Strategy Builder produces NinjaScript code too. Editing C# gives access to logic and APIs beyond the wizard, but handwritten code is not inherently faster. Compare equivalent algorithms and configurations when measuring optimization time.

  • Strategy Builder: Fast point-and-click setup, ideal for testing simple indicator ideas without programming knowledge
  • Custom NinjaScript: Full control over order states, bracket modifications, complex exit logic, and performance optimization
  • Transition path: You can export Strategy Builder logic to C# to examine its generated code and customize it further

Adding a positive MACD (zero-line) filter

A common weakness of raw MACD crossovers is whipsawing during consolidation or choppy markets. Requiring a "positive MACD" for long entries means the MACD line must be above zero when the bullish crossover occurs.

A positive MACD means the fast EMA exceeds the slow EMA on the selected series. A negative value reverses that relationship; neither proves a broader trend or avoids whipsaws. The example uses one RequirePositiveMacd toggle for both long and short filters.

  • RequirePositiveMacd = true: Long entries require both CrossAbove and macd[0] > 0
  • RequirePositiveMacd = true: Short entries also require CrossBelow and macd[0] < 0
  • Effect: excludes crossovers on the opposite side of zero; compare the resulting trades after costs.

Protective orders and risk management

A trading strategy is incomplete without defined risk rules. In NinjaScript, SetProfitTarget and SetStopLoss allow you to configure managed bracket orders directly in State.DataLoaded.

CalculationMode.Ticks defines requested price distances, such as a 20-tick target and 15-tick stop. Managed protection is submitted in response to entries; gaps, slippage, rejection, disconnection, and partial fills can change realized losses and rewards.

  • SetProfitTarget("MacdLong", CalculationMode.Ticks, TargetTicks)
  • SetStopLoss("MacdLong", CalculationMode.Ticks, StopLossTicks, false)
  • Session-close handling attempts to exit around the configured session boundary; it is not a guarantee against gaps or failed exits.

Backtesting your MACD strategy in Strategy Analyzer

Before deploying any strategy, test it in NinjaTrader Strategy Analyzer across multiple market cycles, including trending, ranging, and high-volatility periods. Review key metrics such as profit factor, maximum drawdown, average trade duration, and win rate.

Reserve data outside the tuning window, or use a documented walk-forward design, to evaluate stability. Those checks can reveal sensitivity but cannot ensure reliable future performance.

Sources and verification

Pineify provides information and code-generation assistance, not investment advice. Generated code, static checks, backtests, simulations, and historical examples cannot predict prices or guarantee returns. Review all code and test it in NinjaTrader Editor, Strategy Analyzer, and a simulation account before considering live use.

Frequently asked questions

Generate Custom MACD Strategies with AI

Describe your MACD parameters, entry filters, and risk rules to get an inspectable, single-file NinjaScript Strategy for NinjaTrader 8.