Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

Help with ATRTrailing Indicator

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Help with ATRTrailing Indicator

    I downloaded the ATRTrailing indicator and noticed something that differs from most other ATR Trailing/VSTOP indicators that I've seen.

    For example, during a downtrend, if the bar closes above the declining trailing stop, the indicator switches to long (trailing stop goes below the bar) on the following bar, not the bar that the event occurs on.

    I've tried to manipulate the code to get this to occur on the bar that it happens on but can't seem to do so. It seems like it should be simple but for some reason it's completely eluding me.

    Would anyone know how this could be done? To clarify, I want the stop (dot on the indicator) to change on the actual bar that changes the trend. So in the attached picture, the circled red dot should shift to a blue dot and re-orient itself to a long trend stop (below the bar) on THAT BAR, not the next bar as it does in the picture.

    Any help would be much appreciated! Code for the indicator below for reference. Thanks!

    Code:
    #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.DrawingTools;
    #endregion
    
    //This namespace holds Indicators in this folder and is required. Do not change it. 
    namespace NinjaTrader.NinjaScript.Indicators
    {
    	public class ATRTrailing : Indicator
    	{
    		private Series<double>	Plotset;
    		private Series<double>	Sideset;
    		private int				counter		= 0;
    		private bool			longval;
    		private double			ratchedval	= 0;
    		private bool			shortval;
    		private double			sigClose	= 0;
    		
    		protected override void OnStateChange()
    		{
    			if (State == State.SetDefaults)
    			{
    				Description = @"Wilder’s Volatility System, developed by and named after Welles Wilder, is a volatility index made up of the ongoing calculated average, the True Range. The consideration of the True Range means that days with a low trading range (little difference between daily high and low), but still showing a clear price difference to the previous day";
    				Name						= "ATRTrailing";
    				Calculate					= Calculate.OnBarClose;
    				IsOverlay					= true;
    				DisplayInDataBox			= true;
    				DrawOnPricePanel			= true;
    				DrawHorizontalGridLines		= true;
    				DrawVerticalGridLines		= true;
    				PaintPriceMarkers			= true;
    				ScaleJustification			= NinjaTrader.Gui.Chart.ScaleJustification.Right;
    				//Disable this property if your indicator requires custom values that cumulate with each new market data event. 
    				//See Help Guide for additional information.
    				IsSuspendedWhileInactive	= true;
    				ATRTimes					= 4;
    				Period						= 10;
    				Ratched						= 0.005;
    				AddPlot(new Stroke(Brushes.Red, 2), PlotStyle.Dot, "Lower");
    				AddPlot(new Stroke(Brushes.Blue, 2), PlotStyle.Dot, "Upper");
    			}
    			else if (State == State.Configure)
    			{
    				Plotset = new Series<double>(this);
    				Sideset = new Series<double>(this);
    			}
    		}
    
    		protected override void OnBarUpdate()
    		{
    			if (CurrentBar < Period)
    				return;
    
    			if (Low[0] < Low[1])
    				Sideset[0] = 0;
    
    			if (High[0] > High[1])
    				Sideset[0] = 1;
    
    			ratchedval = (1 - (counter * Ratched));
    
    			if (Sideset[1] == 0)
    			{
    				sigClose = MIN(Low, (Period))[0];
    				Plotset[0] = (sigClose + Instrument.MasterInstrument.RoundToTickSize((ratchedval * (ATRTimes * ATR(Period)[0]))));
    			}
    
    			if (Sideset[1] == 1)
    			{
    				sigClose = MAX(High, (Period))[0];
    				Plotset[0] = (sigClose - Instrument.MasterInstrument.RoundToTickSize((ratchedval * (ATRTimes * ATR(Period)[0]))));
    			}
    
    			if (Sideset[1] == 1 && Low[1] <= Plotset[1])
    			{
    				Sideset[0] = 0;
    				sigClose = High[1];
    				counter = 0;
    				Plotset[0] = (sigClose + Instrument.MasterInstrument.RoundToTickSize((ratchedval * (ATRTimes * ATR(Period)[0]))));
    				Lower[0] = Plotset[0];
    			}
    
    			if (Sideset[1] == 1 && Low[1] > Plotset[1])
    			{
    				Sideset[0] = 1;
    				sigClose = MAX(High, (Period))[0];
    				Plotset[0] = (sigClose - Instrument.MasterInstrument.RoundToTickSize((ratchedval * (ATRTimes * ATR(Period)[0]))));
    				if (Plotset[1] > Plotset[0])
    					Plotset[0] = Plotset[1];
    				Upper[0] = Plotset[0];
    			}
    
    			if (Sideset[1] == 0 && High[1] >= Plotset[1])
    			{
    				Sideset[0] = 1;
    				sigClose = High[1];
    				counter = 0;
    				Plotset[0] = (sigClose - Instrument.MasterInstrument.RoundToTickSize((ratchedval * (ATRTimes * ATR(Period)[0]))));
    				Upper[0] = Plotset[0];
    			}
    
    			if (Sideset[1] == 0 && High[1] < Plotset[1])
    			{
    				Sideset[0] = 0;
    				sigClose = MIN(Low, (Period))[0];
    				Plotset[0] = (sigClose + Instrument.MasterInstrument.RoundToTickSize((ratchedval * (ATRTimes * ATR(Period)[0]))));
    				if (Plotset[1] < Plotset[0])
    					Plotset[0] = Plotset[1];
    				Lower[0] = Plotset[0];
    			}
    
    			counter++;
    		}
    
    		#region Properties
    		[Range(1, double.MaxValue)]
    		[NinjaScriptProperty]
    		[Display(Name="ATRTimes", Description="Number of ATR (Ex. 3 Time ATR)", Order=1, GroupName="Parameters")]
    		public double ATRTimes
    		{ get; set; }
    
    		[Range(1, int.MaxValue)]
    		[NinjaScriptProperty]
    		[Display(Name="Period", Order=2, GroupName="Parameters")]
    		public int Period
    		{ get; set; }
    
    		[Range(0, double.MaxValue)]
    		[NinjaScriptProperty]
    		[Display(Name = "Ratchet Percent", Description = "Ratchet Percent", Order = 3, GroupName = "Parameters")]
    		public double Ratched
    		{ get; set; }
    
    		[Browsable(false)]
    		[XmlIgnore]
    		public Series<double> Lower
    		{
    			get { return Values[0]; }
    		}
    
    		[Browsable(false)]
    		[XmlIgnore]
    		public Series<double> Upper
    		{
    			get { return Values[1]; }
    		}
    		#endregion
    
    	}
    }
    
    #region NinjaScript generated code. Neither change nor remove.
    
    namespace NinjaTrader.NinjaScript.Indicators
    {
    	public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
    	{
    		private ATRTrailing[] cacheATRTrailing;
    		public ATRTrailing ATRTrailing(double aTRTimes, int period, double ratched)
    		{
    			return ATRTrailing(Input, aTRTimes, period, ratched);
    		}
    
    		public ATRTrailing ATRTrailing(ISeries<double> input, double aTRTimes, int period, double ratched)
    		{
    			if (cacheATRTrailing != null)
    				for (int idx = 0; idx < cacheATRTrailing.Length; idx++)
    					if (cacheATRTrailing[idx] != null && cacheATRTrailing[idx].ATRTimes == aTRTimes && cacheATRTrailing[idx].Period == period && cacheATRTrailing[idx].Ratched == ratched && cacheATRTrailing[idx].EqualsInput(input))
    						return cacheATRTrailing[idx];
    			return CacheIndicator<ATRTrailing>(new ATRTrailing(){ ATRTimes = aTRTimes, Period = period, Ratched = ratched }, input, ref cacheATRTrailing);
    		}
    	}
    }
    
    namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
    {
    	public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
    	{
    		public Indicators.ATRTrailing ATRTrailing(double aTRTimes, int period, double ratched)
    		{
    			return indicator.ATRTrailing(Input, aTRTimes, period, ratched);
    		}
    
    		public Indicators.ATRTrailing ATRTrailing(ISeries<double> input , double aTRTimes, int period, double ratched)
    		{
    			return indicator.ATRTrailing(input, aTRTimes, period, ratched);
    		}
    	}
    }
    
    namespace NinjaTrader.NinjaScript.Strategies
    {
    	public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
    	{
    		public Indicators.ATRTrailing ATRTrailing(double aTRTimes, int period, double ratched)
    		{
    			return indicator.ATRTrailing(Input, aTRTimes, period, ratched);
    		}
    
    		public Indicators.ATRTrailing ATRTrailing(ISeries<double> input , double aTRTimes, int period, double ratched)
    		{
    			return indicator.ATRTrailing(input, aTRTimes, period, ratched);
    		}
    	}
    }
    
    #endregion
    Attached Files

    #2
    Hello fiddich,

    Thanks for your post and welcome to the forums!

    In the support department at NinjaTrader we do not create, debug, or modify code for our clients. This is so that we can maintain a high level of service for all of our clients.

    What I suggest is to use a debugging process to help you see what values are being considered in each of the conditional statements. This is the way to fully understand bar by bar what is actually happening, tedious but educational.

    It would seem that a check to see if the current value of the Lower or Upper plot can be compared to the Price High[0], or Low[0] to see if the plotted value is inside the bar and then adjust from there. So you might start with examining the price High, Low and Lower[0] and Upper[0].

    Alternatively or in addition to, here is an example of some diagnostic code to show a dot when the unwanted conditions are met:

    Code:
    			if (Lower[0] <= High[0])
    			{
    				Draw.Dot (this, "T"+CurrentBar, true, 0, High[0]+4 * TickSize, Brushes.Orange);
    			}
    			if (Upper[0] >= Low[0])
    			{
    				Draw.Dot (this, "s"+CurrentBar, true, 0, Low[0]-4 * TickSize, Brushes.Magenta);
    			}
    You can review our debugging tips here: https://ninjatrader.com/support/foru...ead.php?t=3418
    Paul H.NinjaTrader Customer Service

    Comment


      #3
      Hi Paul,

      Thanks for the reply.

      Understood regarding your policy but could you help me understand why what you mentioned would help me (I put the code in and see the dots but am not sure what to do with it)? Everything in the indicator already seems to work fine except for the 1 bar delay when the stop switches from short to long and vice versa. I'm definitely interested in trying to debug it but just want to understand the best approach and reasoning.

      I've only coded a few things in NT7 and NT8 so far, so please forgive my lack of experience in case what you suggested will get me there. Appreciate your help.

      fiddich

      Comment


        #4
        Hello fiddich,

        Thanks for your reply.

        The dots are a way to visualize when a condition is true. If the conditions are true when you do not expect them to be (or false when you expect them to be true) then that can be a clue to look deeper (earlier) in the code to find the conditions that are creating the undesired effect. An alternative and more thorough approach would be to use print statements as explained in the debugging tips reference. Basically, in debugging, you have to understand the values that are being produced in each section of your code and then you can change the code to compensate for what may not be correct or desired.
        Paul H.NinjaTrader Customer Service

        Comment


          #5
          Thanks.

          Alright, I will try to see if I can debug and figure out what's causing this but if there's anyone else out there with more programming experience that might be able to point me in the right direction, I'd really appreciate it.

          Comment

          Latest Posts

          Collapse

          Topics Statistics Last Post
          Started by terofs, Yesterday, 04:18 PM
          1 response
          21 views
          0 likes
          Last Post terofs
          by terofs
           
          Started by CommonWhale, Today, 09:55 AM
          1 response
          3 views
          0 likes
          Last Post NinjaTrader_Erick  
          Started by Gerik, Today, 09:40 AM
          2 responses
          7 views
          0 likes
          Last Post Gerik
          by Gerik
           
          Started by RookieTrader, Today, 09:37 AM
          2 responses
          13 views
          0 likes
          Last Post RookieTrader  
          Started by alifarahani, Today, 09:40 AM
          1 response
          7 views
          0 likes
          Last Post NinjaTrader_Jesse  
          Working...
          X