// // Copyright (C) 2021, NinjaTrader LLC . // NinjaTrader reserves the right to modify or overwrite this NinjaScript component with each release. // #region Using declarations using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Xml.Serialization; using NinjaTrader.Cbi; using NinjaTrader.Gui; using NinjaTrader.Gui.Chart; using NinjaTrader.Gui.SuperDom; using NinjaTrader.Data; using NinjaTrader.NinjaScript; using NinjaTrader.Core.FloatingPoint; using NinjaTrader.NinjaScript.Indicators; using NinjaTrader.NinjaScript.DrawingTools; using NinjaTrader.NinjaScript.Indicators.TDU; #endregion /* ES : TP 4, extra 1 YM : TP 10, extra 2 NQ : TP 7, extra 2 RTY: TP 4, extra 8 */ namespace NinjaTrader.NinjaScript.Strategies { public class SupportResistanceStrategy : Strategy { private TDUSupportResistance _sr; private int _lastBar = 0; private double _lastLevel; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = "TDU Support/Resistance strategy"; Name = "TDU Support/Resistance strategy"; TakeProfit = 20; IsInstantiatedOnEachOptimizationIteration = false; Calculate = Calculate.OnEachTick; ExtraSLTicks = 2; ExtraRetracementTicks = 2; MinTouches = 0; IncludeCommission = true; RealtimeErrorHandling = RealtimeErrorHandling.IgnoreAllErrors; IsExitOnSessionCloseStrategy = false; } else if (State == State.Configure) { AddDataSeries(BarsPeriodType.Tick, 1); } else if (State == State.DataLoaded) { _sr = TDUSupportResistance(Close, TDUSRZoneType.Line,10,16,16,50,15,15,TDUZoneBreakType.CandleClosesOutsideZone,false,BarsPeriodType.Minute,5,1000); _sr.ShowBrokenLines = false; _sr.ShowBroken = false; _sr.ShowPreviousTouches= false; _sr.ShowPrice= false; _sr.ShowPreviousTouchesCount=false; AddChartIndicator(_sr); } } protected override void OnBarUpdate() { if (BarsInProgress != 0) return; if (CurrentBar < BarsRequiredToTrade) return; if (_lastBar == CurrentBar) return; if (Position.MarketPosition == MarketPosition.Flat) { var support = _sr.SupportPrice[0]; if (Low[0] <= support && Close[0] >= support + ExtraRetracementTicks * TickSize) { if (_sr.SupportTouches[0] >= MinTouches) { if (_lastLevel.ApproxCompare(support) != 0) { _lastBar = CurrentBar; _lastLevel = support; SetProfitTarget(CalculationMode.Ticks, TakeProfit); var ticks = (Close[0] - Low[0]) / TickSize; if (ticks < 4) ticks = 4; ticks += ExtraSLTicks; SetStopLoss(CalculationMode.Ticks, ticks); EnterLong(1, 1, "buy"); return; } } } var resistance = _sr.ResistancePrice[0]; if (High[0] >= resistance && Close[0] < resistance - ExtraRetracementTicks * TickSize) { if (_sr.ResistanceTouches[0] >= MinTouches) { if (_lastLevel.ApproxCompare(resistance) != 0) { _lastBar = CurrentBar; _lastLevel = resistance; SetProfitTarget(CalculationMode.Ticks, TakeProfit); var ticks = (High[0] - Close[0]) / TickSize; if (ticks < 4) ticks = 4; ticks += ExtraSLTicks; SetStopLoss(CalculationMode.Ticks, ticks); EnterShort(1, 1, "sell"); return; } } } } } #region Properties [Range(1, int.MaxValue), NinjaScriptProperty] [Display(ResourceType = typeof(Custom.Resource), Name = "Take Profit (ticks)", GroupName = "01. Parameters", Order = 0)] public int TakeProfit { get; set; } [Range(0, int.MaxValue), NinjaScriptProperty] [Display(ResourceType = typeof(Custom.Resource), Name = "Extra SL (ticks)", GroupName = "01. Parameters", Order = 1)] public int ExtraSLTicks { get; set; } [Range(0, int.MaxValue), NinjaScriptProperty] [Display(ResourceType = typeof(Custom.Resource), Name = "Extra Retracement (ticks)", GroupName = "01. Parameters", Order = 2)] public int ExtraRetracementTicks { get; set; } [Range(0, int.MaxValue), NinjaScriptProperty] [Display(ResourceType = typeof(Custom.Resource), Name = "Min. Touches", GroupName = "01. Parameters", Order = 3)] public int MinTouches { get; set; } #endregion } }