Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Adding line 1 x ATR above High of Candle

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

    Adding line 1 x ATR above High of Candle

    Hi

    Couple of questions I was hoping to get some help with:

    Question 1

    I'm trying to update my indicator script to draw some lines onto my chart at 5 pips, 20 pips, 1 x ATR and 1.5 x ATR above the high of my candle that meets certain conditions.

    I tried using the strategy builder to help write the code, and I managed to get the 5 and 20 pips line ok but for the ATR I got the following line:

    Code:
    Draw.Line(this, @"FTB3 Line_2", false, 0, (High[0] + (ATR1[0] * (TickSize * 10))) , 0, (High[0] + (ATR1[0] * (TickSize * 10))) , Brushes.CornflowerBlue, DashStyleHelper.Dash, 1);
    When I run this, I get an error
    Indicator '_indFTB1': Error on calling 'OnBarUpdate' method on bar 27: Object reference not set to an instance of an object.
    .

    Running through Visual Studio I can see it is the above line of code causing the problem.

    The full version of the code is below. Could you help point me in the right direction to get this going?

    Question 2

    What I'd eventually like to do is have an indicator where I can click on a candle and it automatically draws in these lines for me (5 Pip, 20 Pip, 1 x ATR, 1.5 x ATR above high of that candle). Is that possible with NT8?

    Many thanks
    Tim

    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.Gui.Tools;
    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 indFTB1 : Indicator
        {
            private Double dStoreHigherOpenOrClose;  // variable to store whether price close or open is higher value
            private Double dOpenClosePct; // variable to store % of bar open/close happens
            private int x = 0;
            private Double s1, s2, s3;
            private ATR ATR1;
    
    
            protected override void OnStateChange()
            {
                if (State == State.SetDefaults)
                {
                    Description                                    = @"Indicator to show potential FTB setups";
                    Name                                        = "_indFTB1";
                    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;
                    dStoreHigherOpenOrClose                        =0;
                    dOpenClosePct                                =0;
                    s1                                            =0;
                    s2                                            =0;
                    s3                                            =0;
                }
                if (BarsInProgress != 0) 
                    return;
    
                else if (State == State.Configure)
                {
                }
            }
    
            protected override void OnBarUpdate()
            {
                //Add your custom indicator logic here.
                     // Set 1
    
                if (CurrentBars[0] < 25)
                    return;
    
                dStoreHigherOpenOrClose = Close[0];
    
                if (Open[0] > Close[0])
                {
                    dStoreHigherOpenOrClose = Open[0];
                }
                // (higher of open/close less low) / (high less low)
    
                dOpenClosePct = ((dStoreHigherOpenOrClose - Low[0]) / (High[0] - Low[0]));
    
    
    
                if ((High[1] > High[2])
                     && (dOpenClosePct <= 0.5)
                     && (High[0] > High[1])
                     && (Times[0][0].TimeOfDay >= new TimeSpan(6, 0, 0))
                     && (Times[0][0].TimeOfDay <= new TimeSpan(10, 0, 0))
                     && (Close[1] > Close[2]))
                     //&& (CurrentBars[0] > 24));
    
                {
    
                x = 0;
    
                for(int i = 1; i < 24; i++)
                {
                    if(Close[i] > Close[i + 1])
                    {
                        x = x + 1;    
                    }
                    else
                    {
                        break;
                    }
                }
    
                //Print ("i " + i.ToString());
                Print ("x " + x.ToString());            
    
                s1 = ((Close[1] - Low[1]) / (High[1] - Low[1])); //% of bar open close for prior candle 1
    
                s2 = (High[0] - Low[x]); //Total no pips in prior bull candles
    
                s3 = ((s2 * 10000) / x); //avg pips per candle in prior bull candles
    
                Print ("CurrentBars[0] " + CurrentBars[0].ToString());
                Print ("dOpenClosePct " + dOpenClosePct.ToString());
                Print ("Open[0] " + Open[0].ToString());
                Print ("Close[0] " + Close[0].ToString());
                Print ("Low[0] " + Low    [0].ToString());
                Print ("High[0] " + High[0].ToString());                    
                Print ("s1 " + s1.ToString());
                Print ("s2 " + s2.ToString());
                Print ("s3 " + s3.ToString());
    
                    Draw.ArrowDown(this, @"FTB0 " + CurrentBars[0].ToString(), true, 0, (High[0] + (1 * (TickSize * 10))) , Brushes.Orange); //draw an orange down arrow over the candle that could be a potential FTB setup
    
                    string myText = string.Format("{0,0:N2}", (dOpenClosePct + (5 * (TickSize * 10))));
                    Draw.Text(this, CurrentBars[0].ToString() + @" Text_1a",myText , 0, Low[0] - 30 * TickSize);
    
                    string myText2 = (x + " bullish");
                    Draw.Text(this, CurrentBars[0].ToString() + @" Text_1b",myText2 , 0, (High[0] + (10 * (TickSize * 10))));
    
    //                string myText3 = string.Format("{0,0:N2}", (s1 + (5 * (TickSize * 10))));
    //                Draw.Text(this, CurrentBars[0].ToString() + @" Text_1c",myText3 , 1, High[0] + (12 * (TickSize * 10)));
    
    //                string myText4 = string.Format("{0,0:N4}", (s2 + (5 * (TickSize * 10))));
    //                Draw.Text(this, CurrentBars[0].ToString() + @" Text_1d",myText4 , 1, High[0] + (14 * (TickSize * 10)));
    
    //                string myText5 = string.Format("{0,0:N2}", (s3 + (5 * (TickSize * 10))));
    //                Draw.Text(this, CurrentBars[0].ToString() + @" Text_1e",myText5 , 1, High[0] + (16 * (TickSize * 10)));
    
                    Draw.Text(this, @"FTB3 Text_1", @"5 pips", 0, (High[0] + (6 * (TickSize * 10))) );
                    Draw.Line(this, @"FTB3 Line_1", true, 0, (High[0] + (5 * (TickSize * 10))) , 10, (High[0] + (5 * (TickSize * 10))) , Brushes.Red, DashStyleHelper.Dash, 1);
                    Draw.Text(this, @"FTB3 Text_1a", @"20 pips", 0, (High[0] + (21 * (TickSize * 10))) );
                    Draw.Line(this, @"FTB3 Line_1a", true, 0, (High[0] + (20 * (TickSize * 10))) , 10, (High[0] + (20 * (TickSize * 10))) , Brushes.Red, DashStyleHelper.Dash, 1);
    
                    Draw.Text(this, @"FTB3 Text_2", @"5 pips", 0, (Low[0] - (6 * (TickSize * 10))) );
                    Draw.Line(this, @"FTB3 Line_2", true, 0, (Low[0] - (5 * (TickSize * 10))) , 10, (Low[0] - (5 * (TickSize * 10))) , Brushes.Green, DashStyleHelper.Dash, 1);
                    Draw.Text(this, @"FTB3 Text_2a", @"20 pips", 0, (Low[0] - (21 * (TickSize * 10))) );
                    Draw.Line(this, @"FTB3 Line_2a", true, 0, (Low[0] - (20 * (TickSize * 10))) , 10, (Low[0] - (20 * (TickSize * 10))) , Brushes.Green, DashStyleHelper.Dash, 1);
    
                    Draw.Line(this, @"FTB3 Line_2", false, 0, (High[0] + (ATR1[0] * (TickSize * 10))) , 0, (High[0] + (ATR1[0] * (TickSize * 10))) , Brushes.CornflowerBlue, DashStyleHelper.Dash, 1);
                }
            }
        }
    }
    
    #region NinjaScript generated code. Neither change nor remove.
    
    namespace NinjaTrader.NinjaScript.Indicators
    {
        public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
        {
            private indFTB1[] cacheindFTB1;
            public indFTB1 indFTB1()
            {
                return indFTB1(Input);
            }
    
            public indFTB1 indFTB1(ISeries<double> input)
            {
                if (cacheindFTB1 != null)
                    for (int idx = 0; idx < cacheindFTB1.Length; idx++)
                        if (cacheindFTB1[idx] != null &&  cacheindFTB1[idx].EqualsInput(input))
                            return cacheindFTB1[idx];
                return CacheIndicator<indFTB1>(new indFTB1(), input, ref cacheindFTB1);
            }
        }
    }
    
    namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
    {
        public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
        {
            public Indicators.indFTB1 indFTB1()
            {
                return indicator.indFTB1(Input);
            }
    
            public Indicators.indFTB1 indFTB1(ISeries<double> input )
            {
                return indicator.indFTB1(input);
            }
        }
    }
    
    namespace NinjaTrader.NinjaScript.Strategies
    {
        public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
        {
            public Indicators.indFTB1 indFTB1()
            {
                return indicator.indFTB1(Input);
            }
    
            public Indicators.indFTB1 indFTB1(ISeries<double> input )
            {
                return indicator.indFTB1(input);
            }
        }
    }
    
    #endregion

    #2
    Hello timcjpfx,

    Thank you for the post.

    From what I can tell, it looks like you did not copy all of the generated code from the builder, that would be the reason for this error.

    The ATR is not currently defined, you only have a variable but have not assigned anything to it. There should be some syntax generated in the builder that ends up in State.DataLoaded which generates the indicator:

    Code:
    else if (State == State.DataLoaded)
    {                
     ATR1                = ATR(Close, 14);
    }
    An unrelated note, you have some bar related logic in OnStateChange, this type of logic needs to go in OnBarUpdate:

    Code:
     if (BarsInProgress != 0) 
                    return;
    Another item I can note since you mentioned visual studio, if you hover the mouse over the objects like "ATR1" it should show null, assuming you are stopped at the line which threw the error. This can help hint at the problem. Object reference not set to an instance of an object means something is being used but it was null when you tried to do that.

    Regarding the click logic, that is technically possible however it is not generally very easy for an indicator to handle mouse events due to the other events the chart already has related to the mouse. A Drawing Object is the suggestion if you need mouse interaction like this, however you cant pull indciator data from a Drawing Object so you would need to essentially recreate the ATR logic in a drawing tool if you were to do that. You can find many posts on the forum here about using the Preview events or PreviewMouseDown/Up or PreviewKeyDown/up events to handle this from the ChartControl. In this situation you are just using the general WPF events and handling the ones you wanted. Getting mouse X/Y and converting to bar data is also possible.

    I look forward to being of further assistance.


    Comment


      #3
      Thanks Jesse, it is working now thanks to your help!

      Comment

      Latest Posts

      Collapse

      Topics Statistics Last Post
      Started by Geovanny Suaza, 02-11-2026, 06:32 PM
      0 responses
      597 views
      0 likes
      Last Post Geovanny Suaza  
      Started by Geovanny Suaza, 02-11-2026, 05:51 PM
      0 responses
      343 views
      1 like
      Last Post Geovanny Suaza  
      Started by Mindset, 02-09-2026, 11:44 AM
      0 responses
      103 views
      0 likes
      Last Post Mindset
      by Mindset
       
      Started by Geovanny Suaza, 02-02-2026, 12:30 PM
      0 responses
      556 views
      1 like
      Last Post Geovanny Suaza  
      Started by RFrosty, 01-28-2026, 06:49 PM
      0 responses
      555 views
      1 like
      Last Post RFrosty
      by RFrosty
       
      Working...
      X