Write the unit beside the number
I record 12 ticks, 1 percent, or another explicit unit in the specification. A bare stop value is not enough to review the risk.
NinjaScript managed Strategy
Write the entry, exit, stop unit, distance, signal name, and bar timing as explicit rules. Pineify can turn that specification into one editable NT8 Strategy file for review and static checking.
using System.ComponentModel.DataAnnotations;
using NinjaTrader.Cbi;
using NinjaTrader.NinjaScript;
namespace NinjaTrader.NinjaScript.Strategies
{
public class EmaTrailExample : Strategy
{
private const string LongSignal = "LongEntry";
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "EmaTrailExample";
Calculate = Calculate.OnBarClose;
BarsRequiredToTrade = 50;
TrailTicks = 12;
}
else if (State == State.Configure)
{
SetTrailStop(
LongSignal,
CalculationMode.Ticks,
TrailTicks,
false);
}
}
protected override void OnBarUpdate()
{
if (CurrentBar < BarsRequiredToTrade)
return;
if (Position.MarketPosition == MarketPosition.Flat
&& CrossAbove(SMA(20), SMA(50), 1))
EnterLong(1, LongSignal);
if (Position.MarketPosition == MarketPosition.Long
&& CrossBelow(SMA(20), SMA(50), 1))
ExitLong("LongExit", LongSignal);
}
[NinjaScriptProperty]
[Range(1, 500)]
[Display(Name = "Trail ticks", GroupName = "Risk", Order = 0)]
public int TrailTicks { get; set; }
}
}The 20 and 50 EMA crossover and 12-tick trail are illustrative test inputs. They are not a recommendation or expected return.
Use SetTrailStop before the associated entry is submitted. For a fixed managed trailing stop, call it in State.Configure with a stable fromEntrySignal, CalculationMode, and distance. SetTrailStop follows favorable price movement according to the Strategy calculation frequency. Compile and test the Strategy in NinjaTrader because a static check cannot validate fills, stop behavior, or performance.
SetTrailStop defines a managed stop that can follow a position as price moves in its favor. NinjaTrader updates the stop based on the Strategy Calculate setting. Calculate.OnBarClose means the strategy processes the rule after a bar closes; it does not request intrabar updates.
The distance unit is explicit. With CalculationMode.Ticks, a value of 12 means twelve instrument ticks. Percent and Pips use different units. Do not copy the same numeric value across modes and assume the risk is unchanged.
The example declares LongEntry once and uses it in both SetTrailStop and EnterLong. That string association tells the managed approach which entry the protective order belongs to. A spelling change in one call can break the intended relationship.
The exit also passes LongEntry as its fromEntrySignal. Stable names make entry, exit, and protection reviewable as one unit. They also matter when a Strategy has more than one entry path.
A fixed trail can be configured in State.Configure, as shown. A dynamic value can be set from OnBarUpdate before entry, but it must be reset when the Strategy returns to flat or the last value can carry into a later trade. The exact reset rule should be visible in the source.
SetTrailStop should not compete with SetStopLoss or SetParabolicStop for the same position. NinjaTrader documents that SetStopLoss takes precedence when both target the same position. Choose one protection model for that signal unless you have a tested reason to change it.
The EMA crossover in the sample makes the order flow easy to see. It does not establish that a 20 and 50 EMA system has an edge. The Strategy still needs commission, slippage, session, instrument, data quality, and order-state assumptions stated before its results can be interpreted.
When reviewing a generated Strategy, check entry frequency, Calculate mode, position gating, signal names, quantity, stop units, and behavior after a rejected or partial order. A clean compile does not answer those questions.
Pineify can generate one complete Strategy source file and run a static C# and supported API check. Move the resulting file into NinjaScript Editor, compile it, and resolve any installation-specific errors. Then use Strategy Analyzer and simulation to observe the actual order sequence.
Inspect individual trades, not only summary metrics. Confirm the initial stop distance, each favorable update, exit association, flat-state reset, gaps, session transitions, and behavior on the intended Calculate mode. Test unseen data separately from the period used to design the rule.
I record 12 ticks, 1 percent, or another explicit unit in the specification. A bare stop value is not enough to review the risk.
I compare the string used by SetTrailStop, EnterLong, and ExitLong. One mismatch can detach protection or close a different entry path.
I use Strategy Analyzer and simulation to verify when the stop appears and moves. Static acceptance cannot establish runtime order behavior.
Generate and revise one complete NT8 Strategy source artifact.
Review lifecycle and series basics before adding managed orders.
Compile the Strategy and use focused diagnostics without changing the trading rule.
Build display-only calculations before turning a signal into order logic.
This page explains NinjaScript development and Pineify code generation. It is not investment advice. Generated code can be wrong, a static check does not replace NinjaScript Editor compilation, and no example promises future results.
Generate one editable NinjaTrader 8 Indicator or Strategy source file and review static C# and supported API diagnostics.
Learn NinjaScript lifecycle, series indexing, plots, guards, compilation, and chart testing from one small Indicator.
Move a NinjaScript file through static preflight, NinjaScript Editor compilation, source-located repairs, and focused Print output.
Build an editable NT8 Indicator with AddPlot, Values, lifecycle methods, parameters, and lookback guards.
State the entry, exit, trail unit, distance, and bar timing. Inspect one complete Strategy file before testing it in NinjaTrader 8.
Build a Trailing Stop Strategy