ATR Indicator on Chart as just a number

Is there a way to edit current NJ ATR indicator or an indicator that would just display the ATR number on the chart?

Thanks

I don’t know of anything that does this already. Have you tried searching the ecosystem? If you don’t mind doing a little coding work you could easily do this by combining the ATR indicator with Draw.Text() in a custom indicator.

You can get the ATR displayed in the chart scale as a number, without a plot.

Add ATR.
Panel: same as input series
Price Marker: Check
Scale Justification: Overlay
Plot Style: Price Box

or, here is an basic indicator I made sometime ago

#region Using declarations
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Windows.Media;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.NinjaScript;
using NinjaTrader.NinjaScript.DrawingTools;
using NinjaTrader.NinjaScript.Indicators;
using System.Xml.Serialization;

#endregion

namespace NinjaTrader.NinjaScript.Indicators
{
public class ATRTextDisplay : Indicator
{
    private ATR atr;
    private string atrLabel;
		private int MyVar;
		private string TopPadding_String;
		private string BottomPadding_String;

		
    protected override void OnStateChange()
    {
        if (State == State.SetDefaults)
        {
            Name = "ATRText";
            Description = "Displays the current ATR value as fixed text on the chart.";
            Calculate = Calculate.OnBarClose;
            IsOverlay = true;
            ATRPeriod = 14;
				
				// My Defaults
				MyVar = 0;
				TextPosition = TextPosition.BottomRight;
				TopPadding = 0;
				BottomPadding = 1;
				TopPadding_String = "";
				BottomPadding_String = "";
				MyBrush	= Brushes.Black;
				MyBackground = Brushes.Transparent;
				MyBackgroundOpacity = 100;
				MyFont = new SimpleFont("Montserrat", 10) { Bold = false };
        }
        else if (State == State.DataLoaded)
        {
            atr = ATR(ATRPeriod);
        }
    }

    protected override void OnBarUpdate()
    {
        if (CurrentBar < ATRPeriod)
            return;

        double currentATR = atr[0];
        atrLabel = $"ATR = {currentATR:F2}";

			//Top & Bottom Padding
			// Run Once
			if (
				MyVar == 0
				)
			{			
				for (int i = 1; i <= TopPadding; I++)
				{
 					TopPadding_String += "\n";
				}
				
				for (int i = 1; i <= BottomPadding; I++)
				{
 					BottomPadding_String += "\n";
				}

				
				// No Loop 
				MyVar = 1;
			}			
			
			
        Draw.TextFixed(this, "ATR", TopPadding_String + atrLabel + BottomPadding_String, TextPosition, MyBrush, MyFont, Brushes.Transparent, MyBackground, MyBackgroundOpacity);
    }
		
		#region Properties

		// ATR
    [Range(1, int.MaxValue)]
    [Display(Name = "ATR Period", Description = "ATR lookback period", Order = 1, GroupName = "Parameters")]
    public int ATRPeriod { get; set; }
		
		//PARAMETER Text Position
		[NinjaScriptProperty]
		[Display(Name="Indicator Position", Order=3, GroupName="Parameters")]
		public TextPosition TextPosition
		{ get; set; }
		
		// PARAMETER Top Padding
		[NinjaScriptProperty]
		[Range(0, 100)]
		[Display(Name="Top Padding", Description="Top Padding", Order=4, GroupName="Parameters")]
		public int TopPadding
		{ get; set; }
		
		// PARAMETER Bottom Padding
		[NinjaScriptProperty]
		[Range(0, 100)]
		[Display(Name="Bottom Padding", Description="Bottom Padding", Order=5, GroupName="Parameters")]
		public int BottomPadding
		{ get; set; }	

		
		// PARAMETER Font
		[Display(ResourceType = typeof(Custom.Resource), Name = "Font", GroupName = "Parameters", Order = 6)]
		public SimpleFont MyFont 
		{ get; set; }
				
		// PARAMETER Brush
		[NinjaScriptProperty]
		[XmlIgnore]
		[Display(Name="MyBrush", Description="My Brush desc", Order=7, GroupName="Parameters")]
		public Brush MyBrush
		{ get; set; }

		[Browsable(false)]
		public string MyBrushSerializable
		{
			get { return Serialize.BrushToString(MyBrush); }
			set { MyBrush = Serialize.StringToBrush(value); }
		}	
		
		// PARAMETER Background
		[NinjaScriptProperty]
		[XmlIgnore]
		[Display(Name="MyBackground", Description="My Background Desc", Order=8, GroupName="Parameters")]
		public Brush MyBackground
		{ get; set; }

		[Browsable(false)]
		public string MyBackgroundSerializable
		{
			get { return Serialize.BrushToString(MyBackground); }
			set { MyBackground = Serialize.StringToBrush(value); }
		}		

		// PARAMETER MyBackground Opacity
		[NinjaScriptProperty]
		[Range(0, 100)]
		[Display(Name="Background Opacity", Description="Background Opacity", Order=9, GroupName="Parameters")]
		public int MyBackgroundOpacity
		{ get; set; }			
		
		#endregion	
}
}

you can see both here:

3 Likes

#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Gui.Chart;
#endregion

// This namespace holds all indicators and is required. Do not change it.
namespace NinjaTrader.Indicator
{
///


///
///
/// *** You may freely distribute this script, but if you make changes please add your comments below
///
/// Revision Author Date Comments
/// ________ ______ ____ ________
/// 1.0 Khoi(Cory) Nguyen
///

[Description("Average Daily Range ")]
public class ADR_Cory : Indicator
{
#region Variables
// Wizard generated variables
// User defined variables (add any user defined variables below)
private DateTime currentDate = Cbi.Globals.MinDate;
private DateTime now,prevDay,prev2Day,prev3Day,startDay,saveBar,countdnDay;

		private int beginTime = 161400;
        private int endTime   = 093000;
		private DateTime startDateTime;
		private DateTime endDateTime;
		private double highestHigh = 0;
		private double lowestLow = 0;
		double adr, adr2, close1, close2 = 0.0;
	
	private double open = 0;
	private double high = 0;
	private double low = 0;
	
	private double adrmean = 0;
	private double adrstd = 0;
	private double adrstddistance = 0;
	private double adrzscore = 0;
	private double adrabovelast = 0;
	private double adrpullback = 0;
	private double adrtotalpos = 0;
	private double adroverext = 0;
	
		private bool gapUp = false;
		private bool gapDn = false;
		private Color rangeColorDn = Color.DarkGoldenrod;
		private int rangeColorOpacity = 2;			
		private Color rangeColorUp = Color.DodgerBlue;
	

	    private int barWidth =3;

		private Font 		tfont = new Font("Arial", 8, FontStyle.Bold, GraphicsUnit.Point);
		private Color barColorUp =   Color.DarkCyan;
		private Color barColorDown = Color.IndianRed;
		private Color barColorNeutral = Color.Gray;
	    private Color barColor = Color.Gray;

		private double 	todaysLow 				= 0;
		private double 	todaysHigh 				= 0;
		private double	todaysRange 			= 0;
	    private int hBar =0;
	    private int lBar =0;
		int daysBack = 5;
		int daycount,daywithdata = 0;
	    int comparevalue = 0;

		bool firstTime = true, firsttimetoday = true;
        int barNotProcess = 0;
        private double[] arrayRange = new double[13000];
    #endregion

    /// <summary>
    /// This method is used to configure the indicator and is called once before any bar data is loaded.
    /// </summary>
    protected override void Initialize()
    {

		CalculateOnBarClose	= false;
        Overlay				= true;
        PriceTypeSupported	= false;
		
		now = DateTime.Today;         // today date
		prevDay  = now.AddDays(-1);   // yesterday date
		prev2Day = now.AddDays(-2); 
		prev3Day = now.AddDays(-3); 
		startDay = now.AddDays(-daysBack);  // days back
		countdnDay = now.AddDays(-daysBack);  // days count down	
    }

    /// <summary>
    /// Called on each bar update event (incoming tick)
    /// </summary>
    protected override void OnBarUpdate()
    {	
		if (Bars == null)
		return;
		//Only allowed on Intraday charts.
		if (!Data.BarsType.GetInstance(Bars.Period.Id).IsIntraday)
		{
			DrawTextFixed("error msg", "Indicator only works on intraday intervals", TextPosition.BottomRight);
			return;
		}
		
		
		
		int sessionsBarsAgo = 0;
	//	DateTime bar = new DateTime(Bars.GetSessionBar(sessionsBarsAgo).Time.Year, Bars.GetSessionBar(sessionsBarsAgo).Time.Month, Bars.GetSessionBar(sessionsBarsAgo).Time.Day, Bars.SessionBegin.Hour, Bars.SessionBegin.Minute, Bars.SessionBegin.Second);
    
	    DateTime bar = Bars.GetTradingDayFromLocal(Time[0]);
    
		string format = "yyyyMMdd";
	//	Print (" bar "+bar.ToString(format)+" startDay "+startDay.ToString(format));
		// filter out date earlier than start date
		int result = (DateTime.Compare(bar, startDay));
		  if (result < 0)
		   return;

	//	Print(CurrentBar+ " bar "+bar+" start day "+startDay+" result "+result);
		// print result if today start
		if (bar.ToString(format) == now.ToString(format))
		{
			if (firsttimetoday)
			{   highestHigh = 0;
		        lowestLow = 999999999.99;
				firsttimetoday = false;
			
			int d = daywithdata;	
				
		//	Print ( "daywith data "+	daywithdata);
				
			while (d > 0)
			{adr = adr + arrayRange[d];
			 d--;
			}	
			adr = adr/daywithdata;
			
			
		//	int ds = daysBack;
		//	while (ds > 0)
		//	{Print ( " hist time "+Bars.GetSessionBar(ds).Time+ " high "+Bars.GetSessionBar(ds).High+ " low "+Bars.GetSessionBar(ds).Low);
		//	 ds--;
		//	}
			
			}
			
							
	//	Print (CurrentBar+ " high0 "+highestHigh+" low0 "+lowestLow);				
		if (High[0] > highestHigh) highestHigh = High[0];		
		if (Low[0] < lowestLow) lowestLow = Low[0];				
		
		todaysLow = lowestLow; 
		todaysHigh = highestHigh; 
		todaysRange = todaysHigh - todaysLow;
				
        string text3 = string.Format("Hist ADR: {0}   Curr ADR: {1}\r\n ", Instrument.MasterInstrument.Round2TickSize(adr), 
		                                                               Instrument.MasterInstrument.Round2TickSize(todaysRange));
		DrawTextFixed("cory", text3,  TextPosition.TopLeft);
		
		// ++++
		open = CurrentDayOHL().CurrentOpen[0];
		high = CurrentDayOHL().CurrentHigh[0];
		low = CurrentDayOHL().CurrentLow[0];
		
	
		close1 = PriorDayOHLC().PriorClose[0]; 
	

	
    //    adrmean = (high - low ) / 2;
	//	if ((adrmean - adr) > 0)
	//	{
	//	Print("ADR left to mean : " + Math.Round(adrmean - adr,2));
	//	}
	//	if ((adrmean - adr) < 0)
	//	{
	//	Print("ADR over mean by: " + Math.Round(adr - adrmean,2) + "%");
	//	}
		
		if (Close[0] > open)
        {
			string text33 = string.Format("\r\n\rPrice: {0}   Open: {1}     Diff: +{2}",Close[0], open, Instrument.MasterInstrument.Round2TickSize(Close[0] - open));
					DrawTextFixed("Nebraska", text33,  TextPosition.TopLeft);
		}
		if (Close[0] < open)
        {
		    string text33 = string.Format("\r\n\rPrice: {0}    Open: {1}     Diff: -{2}",Close[0] , open, Instrument.MasterInstrument.Round2TickSize(open -Close[0]));
			DrawTextFixed("Nebraska", text33,  TextPosition.TopLeft);
		}
		
		if (Close[0] > close1)
        {
			string text4 = string.Format("\n\n\rPrice: {0}    Prior Close: {1}    Diff: +{2}",Close[0], close1, Instrument.MasterInstrument.Round2TickSize(Close[0] - close1));
					DrawTextFixed("aa", text4,  TextPosition.TopLeft);
		}
		if (Close[0] < close1)
        {
		    string text4 = string.Format("\n\n\rPrice: {0}     Prior Close: {1}    Diff: -{2}",Close[0] , close1, Instrument.MasterInstrument.Round2TickSize(close1 -Close[0]));
			DrawTextFixed("aa", text4,  TextPosition.TopLeft);
		}
		
		}
		
	else {

		countdnDay = now.AddDays(-daysBack+daycount);
		int result2 = (DateTime.Compare(bar, countdnDay));

	//	Print(CurrentBar+ " bar "+bar+" cdndat "+countdnDay+" result2 "+result2);    
		
		if (result2 == 0)
		{						
		if (firstTime)
			
		{
			highestHigh = 0;
			lowestLow = 999999999.99;	
			firstTime = false;
			saveBar = countdnDay;
			daywithdata = 1;
		}
//		Print(CurrentBar+ " savebar "+saveBar+" cdnday "+countdnDay);  
		
		int result3 = (DateTime.Compare(saveBar, countdnDay));
		if (result3 != 0)
		{saveBar = countdnDay;
		 daywithdata = daywithdata + 1;
		 highestHigh = 0;
		 lowestLow = 999999999.99;	
		}
	    while (barNotProcess > 0)
		{
		if (High[barNotProcess] > highestHigh) highestHigh = High[barNotProcess];		
		if (Low[barNotProcess] < lowestLow) lowestLow = Low[barNotProcess];		
		
		barNotProcess--;
		}
//		Print(CurrentBar+ " savebar "+saveBar+" cdnday "+countdnDay+"  result3 "+result3+ " daywdata "+daywithdata);  
		
		
		if (High[0] > highestHigh)
		{
			highestHigh = High[0];
			hBar = CurrentBar;
//			DrawDiamond("Stop High" , 0, High[0] + TickSize, Color.Red);
		
		}
		if (Low[0] < lowestLow) 
		{
			lowestLow = Low[0];
			lBar = CurrentBar;
//			DrawDiamond("Stop Low"  , 0, Low[0] - TickSize, Color.Blue);
			
		}

        arrayRange[daywithdata] = Instrument.MasterInstrument.Round2TickSize(highestHigh - lowestLow);
//		Print (" days= "+daywithdata+ " high= "+highestHigh+" low= "+lowestLow+ " adr "+arrayRange[daywithdata]);		
		
		}
		else 
//			if (!firstTime)
		       { daycount = daycount + 1;	
				 barNotProcess = barNotProcess + 1;
		       }
		
		
		}   // end of getting H/L value 
		
		
    }     // end on bar update

	 
    #region Properties
	[Description("Number of Days Back includes Sat. Sun.")]
	[Category("Parameters")]
	[Gui.Design.DisplayName("Days to calculate ADR")]
	public int DayBack
	{
		get { return daysBack; }
		set { daysBack = Math.Max(value, 0); }
	}

    #endregion
}

}

#region NinjaScript generated code. Neither change nor remove.
// This namespace holds all indicators and is required. Do not change it.
namespace NinjaTrader.Indicator
{
public partial class Indicator : IndicatorBase
{
private ADR_Cory cacheADR_Cory = null;

    private static ADR_Cory checkADR_Cory = new ADR_Cory();

    /// <summary>
    /// Average Daily Range 
    /// </summary>
    /// <returns></returns>
    public ADR_Cory ADR_Cory(int dayBack)
    {
        return ADR_Cory(Input, dayBack);
    }

    /// <summary>
    /// Average Daily Range 
    /// </summary>
    /// <returns></returns>
    public ADR_Cory ADR_Cory(Data.IDataSeries input, int dayBack)
    {
        if (cacheADR_Cory != null)
            for (int idx = 0; idx < cacheADR_Cory.Length; idx++)
                if (cacheADR_Cory[idx].DayBack == dayBack && cacheADR_Cory[idx].EqualsInput(input))
                    return cacheADR_Cory[idx];

        lock (checkADR_Cory)
        {
            checkADR_Cory.DayBack = dayBack;
            dayBack = checkADR_Cory.DayBack;

            if (cacheADR_Cory != null)
                for (int idx = 0; idx < cacheADR_Cory.Length; idx++)
                    if (cacheADR_Cory[idx].DayBack == dayBack && cacheADR_Cory[idx].EqualsInput(input))
                        return cacheADR_Cory[idx];

            ADR_Cory indicator = new ADR_Cory();
            indicator.BarsRequired = BarsRequired;
            indicator.CalculateOnBarClose = CalculateOnBarClose;

#if NT7
indicator.ForceMaximumBarsLookBack256 = ForceMaximumBarsLookBack256;
indicator.MaximumBarsLookBack = MaximumBarsLookBack;
#endif
indicator.Input = input;
indicator.DayBack = dayBack;
Indicators.Add(indicator);
indicator.SetUp();

            ADR_Cory[] tmp = new ADR_Cory[cacheADR_Cory == null ? 1 : cacheADR_Cory.Length + 1];
            if (cacheADR_Cory != null)
                cacheADR_Cory.CopyTo(tmp, 0);
            tmp[tmp.Length - 1] = indicator;
            cacheADR_Cory = tmp;
            return indicator;
        }
    }
}

}

// This namespace holds all market analyzer column definitions and is required. Do not change it.
namespace NinjaTrader.MarketAnalyzer
{
public partial class Column : ColumnBase
{
///


/// Average Daily Range
///

///
[Gui.Design.WizardCondition(“Indicator”)]
public Indicator.ADR_Cory ADR_Cory(int dayBack)
{
return _indicator.ADR_Cory(Input, dayBack);
}

    /// <summary>
    /// Average Daily Range 
    /// </summary>
    /// <returns></returns>
    public Indicator.ADR_Cory ADR_Cory(Data.IDataSeries input, int dayBack)
    {
        return _indicator.ADR_Cory(input, dayBack);
    }
}

}

// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
public partial class Strategy : StrategyBase
{
///


/// Average Daily Range
///

///
[Gui.Design.WizardCondition(“Indicator”)]
public Indicator.ADR_Cory ADR_Cory(int dayBack)
{
return _indicator.ADR_Cory(Input, dayBack);
}

    /// <summary>
    /// Average Daily Range 
    /// </summary>
    /// <returns></returns>
    public Indicator.ADR_Cory ADR_Cory(Data.IDataSeries input, int dayBack)
    {
        if (InInitialize && input == null)
            throw new ArgumentException("You only can access an indicator with the default input/bar series from within the 'Initialize()' method");

        return _indicator.ADR_Cory(input, dayBack);
    }
}

}
#endregion

1 Like

Thank you all, much appreciated!

I tried adding your script but continue to get error messages, I’ve never done this before so I don’t really know what I’m doing.

open the NinjaScript editor, right click indicators > new indicator:

name the file, click generate

paste the code, then click compile:

Thanks for the instructions. I keep getting two error messages when compiling.

I think the forum software changed something.

See the capital I on line 72 and 77, make it a small lowercase i

1 Like

That worked, thanks for your help!