#region Using declarations using NinjaTrader.Cbi; using NinjaTrader.NinjaScript.Indicators; using System; using System.ComponentModel.DataAnnotations; #endregion namespace NinjaTrader.NinjaScript.Strategies { public class FirstCrossBot : Strategy { private SMA fastMA; private SMA slowMA; private SMA oscillatorMA; private Series oscillator; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Taken from chapter 24 of Kaufman Constructs Trading Systems"; Name = "1st Cross Bot"; 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; FastPeriod = 17; SlowPeriod = 45; OscillatorPeriod = 5; LongOnly = true; } else if (State == State.Configure) { } else if (State == State.DataLoaded) { fastMA = SMA(FastPeriod); slowMA = SMA(SlowPeriod); oscillator = new Series(this); oscillatorMA = SMA(oscillator, OscillatorPeriod); } } protected override void OnBarUpdate() { if (CurrentBar < Math.Max(FastPeriod, Math.Max(SlowPeriod, OscillatorPeriod))) return; oscillator[0] = fastMA[0] - slowMA[0]; bool isCrossAbove = CrossAbove(oscillator, oscillatorMA, 1); bool isCrossBelow = CrossBelow(oscillator, oscillatorMA, 1); if (isCrossAbove && Low[0] > Low[1]) EnterLong(); else if (isCrossBelow && High[0] < High[1] && !LongOnly) EnterShort(); if (Position.MarketPosition == MarketPosition.Long && isCrossBelow) ExitLong(); else if (Position.MarketPosition == MarketPosition.Short && isCrossAbove) ExitShort(); } public override string DisplayName { get { return Name; } } [Range(1, int.MaxValue), NinjaScriptProperty] [Display(Name = "Fast Period", GroupName = "1st Cross Bot", Order = 1)] public int FastPeriod { get; set; } [Range(1, int.MaxValue), NinjaScriptProperty] [Display(Name = "Slow Period", GroupName = "1st Cross Bot", Order = 2)] public int SlowPeriod { get; set; } [Range(1, int.MaxValue), NinjaScriptProperty] [Display(Name = "Oscillator Period", GroupName = "1st Cross Bot", Order = 3)] public int OscillatorPeriod { get; set; } [NinjaScriptProperty] [Display(Name = "Long Only", GroupName = "1st Cross Bot", Order = 4)] public bool LongOnly { get; set; } } }