#region Using declarations using System; using System.ComponentModel.DataAnnotations; using NinjaTrader.Cbi; using NinjaTrader.NinjaScript.Indicators; #endregion //This namespace holds Strategies in this folder and is required. Do not change it. namespace NinjaTrader.NinjaScript.Strategies { public class TrendFollowing : Strategy { private ATR atr; private MovingAverage movingAverage; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Determines trend based on moving average slope, takes longs only"; Name = "Trend Following"; Calculate = Calculate.OnBarClose; EntriesPerDirection = 1; EntryHandling = EntryHandling.AllEntries; IsExitOnSessionCloseStrategy = true; ExitOnSessionCloseSeconds = 30; IsFillLimitOnTouch = false; MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix; OrderFillResolution = OrderFillResolution.Standard; Slippage = 0; StartBehavior = StartBehavior.WaitUntilFlat; TimeInForce = TimeInForce.Gtc; TraceOrders = false; RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose; StopTargetHandling = StopTargetHandling.PerEntryExecution; BarsRequiredToTrade = 20; IsInstantiatedOnEachOptimizationIteration = true; MovingAveragePeriod = 100; TakeProfit = false; ATRPeriod = 14; ATRMultiplier = 2; } else if (State == State.DataLoaded) { atr = ATR(ATRPeriod); movingAverage = MovingAverage(MovingAveragePeriod); } } protected override void OnBarUpdate() { if (CurrentBar < Math.Max(MovingAveragePeriod, ATRPeriod)) return; double atrValue = atr[0]; double profitTarget = ATRMultiplier * atrValue; if (movingAverage[0] > movingAverage[1]) { EnterLong(); if (TakeProfit) SetProfitTarget(CalculationMode.Ticks, profitTarget / TickSize); } else if (movingAverage[0] < movingAverage[1]) { ExitLong(); } } public override string DisplayName { get { return Name; } } [Range(1, int.MaxValue), NinjaScriptProperty] [Display(Name = "Moving Average Period", GroupName = "Trend Following", Order = 1)] public int MovingAveragePeriod { get; set; } [Display(Name = "Take Profit", GroupName = "Trend Following", Order = 2)] public bool TakeProfit { get; set; } [Range(1, int.MaxValue), NinjaScriptProperty] [Display(Name = "ATR Period", GroupName = "Trend Following", Order = 3)] public int ATRPeriod { get; set; } [Range(0.1, double.MaxValue), NinjaScriptProperty] [Display(Name = "ATR Multiplier", GroupName = "Trend Following", Order = 4)] public double ATRMultiplier { get; set; } } }