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 using AddDataSeries for Multi Time Frame ATR Level

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

    Help with using AddDataSeries for Multi Time Frame ATR Level

    Hey all,

    I'm extremely new to C# and coding in general but having fun completing the training/sample indicators in the educational resources. After completing those I decided to attempt one on my own and of course, didn't get too far lol.

    I'm trying to create an ATR level indicator. It will be plotted on lower timeframes like minute and tick charts and use a WildersMovingAverage of the 14-period Daily ATR. From those values and the daily close, it will plot the High and Low ATR levels as a line.

    I've attached the incomplete indicator and any help or guidance would be greatly appreciated. I have also looked at the documentation for AddDataSeries and using BarsArrays but haven't grasped how to use them correctly so tips in that area would be awesome.

    Take a peek and let me know where I went off track.

    Thanks.

    Happy Holidays and Happy Birthday to Jesus
    Attached Files
    Last edited by MTGTrading; 12-24-2023, 10:29 PM. Reason: Replaced previous compiled indicator with updated version that has print statements

    #2
    Hello MTGTrading,

    Thanks for your post.

    So I may accurately assist, do you see an error in the Log tab of the Control Center when testing the script?

    If so, what exactly does the error message state? Please provide a screenshot of the error message.
    • To send a screenshot with Windows 10 or newer I would recommend using the Windows Snipping Tool.
    • Alternatively to send a screenshot press Alt + PRINT SCREEN to take a screenshot of the selected window. Then go to Start--> Accessories--> Paint, and press CTRL + V to paste the image. Lastly, save it as a jpeg file and send the file as an attachment.
    ​Note that plots will only apply/display to the primary series the strategy is running on in a multi-timeframe/multi-instrument NinjaScript.

    To get this Open, High, Low, and Close price of the added series, you should use the plural Opens, Highs, Lows, and Closes.

    For example, Closes[1][0] would get the current close price of the added series.

    See this help guide page: https://ninjatrader.com/support/help...riceseries.htm

    This help guide page is also important to review for more information about working with Multi-Timeframe/Multi-Instrument NinjaScripts: https://ninjatrader.com/support/help...nstruments.htm

    And, to understand exactly how your logic is behaving you must add debugging prints to the script that prints out all of the values being used to see how they are evaluating.

    Below is a link to a forum post that demonstrates how to use prints to understand behavior.
    https://ninjatrader.com/support/foru...121#post791121
    Brandon H.NinjaTrader Customer Service

    Comment


      #3
      Hi BrandonH,

      Thanks for jumping in to help. The links were really helpful although I may have to read them a few more times as I'm sure I can still gain some important nuggets from them.

      Fortunately no errors in the Log tab. As you suggested I added a few print statements to see how far along the script would go and did get an error in the output window(image attached).

      I'm not quite sure what the error means yet and how it relates to my script but I'm gonna search the forum for those keywords.
      Attached Files

      Comment


        #4
        Hello MTGTrading,

        Thank you for your reply.

        The message "Object reference not set to an instance of an object" can typically be resolved by checking for null references prior to accessing the value of a variable. This is explained on the following help guide page:


        You could still use print statements to narrow down which particular line of code in OnBarUpdate() is causing the error. Hopefully with those tips in mind and using print statements you can identify the cause and implement a resolution. Otherwise, please share a snippet of your code and we would be glad to provide you with example prints to use to move forward in the debugging process.

        Please let us know if we may be of further assistance.
        Emily C.NinjaTrader Customer Service

        Comment


          #5
          Hi NinjaTrader_Emily,

          Thank you for the additional help. Even after reading the info in the link, I'm still not too sure how to implement the null reference checks as all of this is still very much a foreign language to me but I did notice that my initial code had a separate calculation issue so I changed it. Didn't fix the error but it should be accurate once the error is fixed.



          [CODE]

          protected override void OnStateChange()
          {
          if (State == State.SetDefaults)
          {
          Description = @"Enter the description for your new custom Indicator here.";
          Name = "mATRHL";
          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;
          Length = 14;
          AddPlot(Brushes.Aqua, "DailyClose");
          AddPlot(Brushes.Red, "HighATR");
          AddPlot(Brushes.Lime, "LowATR");
          }
          else if (State == State.Configure)
          {
          AddDataSeries(Data.BarsPeriodType.Day, 1);
          }
          else if (State == State.DataLoaded)
          {
          a1 = new Series<double>(this);
          }
          }

          protected override void OnBarUpdate()
          {
          Print("Code has entered OnBarUpdate");

          if (CurrentBar <= BarsRequiredToPlot) return;

          Print("Code has passed BarsRequiredToPlot ");

          if (BarsInProgress == 1)
          {
          Print("Code has entered BarsInProgress==1");
          var high1 = MAX(Highs[0], Length)[0];
          var close1 = BarsArray[1].GetClose(0);
          var low1 = MIN(Lows[0], Length)[0];
          a1[0] = Math.Max(Math.Abs(low1 - close1), Math.Max(high1 - low1, Math.Abs(high1- close1)));
          var ma = WildersMA(a1, 10)[0];
          var dailyclose1 = Close[0];

          var hatr = dailyclose1 + ma;
          var latr = dailyclose1 - ma;

          Values[0][0] = dailyclose1;
          Values[0][1] = hatr;
          Values[0][2] = latr;

          }
          Print(string.Format("{0} | MAX(Highs[0], Length)[0]: {1} BarsArray[1].GetClose(10): {2} MIN(Lows[0], Length)[0]: {3} " +
          " Close[0]: {4} a1[0]: {5} WildersMA(a1, 10)[0]: {6} ",
          Time[0], BarsArray[1].GetHigh(10), BarsArray[1].GetClose(10), BarsArray[1].GetLow(10), Close[0],
          a1[0], WildersMA(a1, 10)[0]));
          }​

          [CODE]




          Not sure if this is the correct way to post a code snippet so if there is a better way please let me know. I have also attached the exported script zip if you'd prefer to use that.
          Attached Files
          Last edited by MTGTrading; 12-26-2023, 04:44 PM.

          Comment


            #6
            Hello MTGTrading,

            Thanks for your notes.

            The error message in question indicates that something is returning null or is not created at the time you are accessing it.

            As NinjaTrader_Emily stated, this could typically be resolved by checking for null references before accessing the value of a variable.

            For example, checking if a variable is not equal (!=) to null before accessing that variable.

            I noticed in the code you shared that you have a CurrentBar condition checking if there are enough bars for the primary series, but you do not have a CurrentBars check to make sure you have enough bars for the added secondary series. As best practice, you should add a CurrentBars condition to check if there are enough bars in the added secondary series also.

            Make sure there are enough bars: https://ninjatrader.com/support/help...nough_bars.htm
            CurrentBars: https://ninjatrader.com/support/help...urrentbars.htm

            The variables in your script should be defined as double variables. Instead of calling var high1, you could call double high1, for example. Or, these could be made as class-level variables and then utilized in OnBarUpdate().

            Further, instead of using BarsArray[1].GetClose(0); in your script you should use the plural of Close (Closes[1[0]) to get the current close price of the secondary added series.

            Closes: https://ninjatrader.com/support/help...nt8/closes.htm

            To narrow in on what exact line of code is causing the error, you could reduce your code by commenting out code line by line and testing to see if the error persists. If at some point you comment out a line of code and see the error stop, it is likely that last line of commented out code causing the error to occur.

            With reducing code, adding debugging prints to the script one line after you are assigning a value to the variable, and checking for null references, you could find the exact line of code causing the error to occur and modify that line of code accordingly.
            Last edited by NinjaTrader_BrandonH; 12-26-2023, 04:40 PM.
            Brandon H.NinjaTrader Customer Service

            Comment


              #7
              Hi NinjaTrader_BrandonH,

              Thank you for the additional tips. Looks like I'm getting closer to getting something that works.

              I've read other forum posts and noticed they were able to post and separate the code from the rest of their post, how can I do that?

              Comment


                #8
                Hello MTGTrading,

                Thanks for your notes.

                The '#' button on the forum post editor toolbar could be used to wrap CODE tags around selected text.

                Attached is a screenshot highlighting where that button is located.

                Or, you could export the script by going to Tools > Export > NinjaScript AddOn and attach the exported script to a reply.
                Attached Files
                Brandon H.NinjaTrader Customer Service

                Comment


                  #9
                  Thanks.

                  So, after fixing the many issues you guys pointed out I'm still getting an error.

                  1) Do you have another example of the null checks you can point me towards as it seems that is still the problem?

                  Code:
                  public class mATRHL : Indicator
                      {
                          private Series<double> a1 = null;
                          private double high1;
                          private double close1;
                          private double low1;
                          private double ma;
                          private double hatr;
                          private double latr;
                  
                          protected override void OnStateChange()
                          {
                              if (State == State.SetDefaults)
                              {
                                  Description                                    = @"Enter the description for your new custom Indicator here.";
                                  Name                                        = "mATRHL";
                                  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;
                                  Length                                        = 2;
                                  AddPlot(Brushes.Aqua, "DailyClose");
                                  AddPlot(Brushes.Red, "HighATR");
                                  AddPlot(Brushes.Lime, "LowATR");
                              }
                              else if (State == State.Configure)
                              {
                                  AddDataSeries(Data.BarsPeriodType.Day, 1);
                              }
                              else if (State == State.DataLoaded)
                              {                
                                  a1 = new Series<double>(this);
                              }
                          }
                  
                          protected override void OnBarUpdate()
                          {
                               Print("Code has entered OnBarUpdate");
                  
                              if (CurrentBar < BarsRequiredToPlot || CurrentBars[1] < Length) return;
                  
                               Print("Code has passed BarsRequiredToPlot ");
                  
                              if (BarsInProgress == 1)
                  
                                  Print("Code has entered BarsInProgress==1");
                  
                                  high1 = MAX(Highs[0], Length)[0];
                                  close1 = Closes[1][0];
                                  low1 = MIN(Lows[0], Length)[0];
                                  a1[0] = Math.Max(Math.Abs(low1 - close1), Math.Max(high1 - low1, Math.Abs(high1- close1)));
                                  ma = WildersMA(a1, 10)[0];
                  
                                  hatr = close1 + ma;
                                  latr = close1 - ma;
                  
                              Print("Code has passed variables");
                  
                                  Values[0][0] = close1;
                                  Values[0][1] = hatr;
                                  Values[0][2] = latr;
                  
                              Print(string.Format("{0} | MAX(Highs[0], Length)[0]: {1}  BarsArray[1].GetClose(10): {2} MIN(Lows[0], Length)[0]: {3} " +
                                  " Close[0]: {4}  a1[0]: {5}  WildersMA(a1, 10)[0]: {6} ",
                              Time[0], BarsArray[1].GetHigh(10), BarsArray[1].GetClose(10), BarsArray[1].GetLow(10), Close[0],
                              a1[0], WildersMA(a1, 10)[0]));
                          }​
                  Attached Files

                  Comment


                    #10
                    Hello MTGTrading,

                    Thanks for your notes.

                    Are you trying to assign "close1" to the first added plot called DailyClose, and assign "hatr" to the second added plot called HighATR, and assign "latr" to the third added plot called LowATR?

                    If so, this would not be the correct syntax for assigning "hart" to the HighATR plot and assigning "latr" to the LowATR plot.

                    Values[1][0] = hatr; should be used to assign "hatr" value to the HighATR plot.

                    Values[2][0] = latr; should be used to assign the "latr" value to the LowATR plot.

                    See the help guide documentation below for more information and sample code.

                    AddPlot(): https://ninjatrader.com/support/help...t8/addplot.htm
                    Values: https://ninjatrader.com/support/help...nt8/values.htm

                    If the error is still occurring you should reduce your code to locate the exact line of code causing the error to occur. This is a process of commenting out a line or lines of code and testing to see if the error message persists. Once you comment out a line or lines of code and see the error stop, it was likely the last piece of commented out code causing the error to occur.

                    Once you determine the line of code causing the error, you could narrow in on the offending code by further debugging that section of code using prints

                    Further, as noted in post # 6:

                    The variables in your script should be defined as double variables. Instead of calling var high1, you should call double high1, for example. Or, these could be made as class-level double variables and then utilized in OnBarUpdate().
                    Brandon H.NinjaTrader Customer Service

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by poplagelu, Today, 05:00 AM
                    0 responses
                    3 views
                    0 likes
                    Last Post poplagelu  
                    Started by fx.practic, 10-15-2013, 12:53 AM
                    5 responses
                    5,407 views
                    0 likes
                    Last Post Bidder
                    by Bidder
                     
                    Started by Shai Samuel, 07-02-2022, 02:46 PM
                    4 responses
                    98 views
                    0 likes
                    Last Post Bidder
                    by Bidder
                     
                    Started by DJ888, Yesterday, 10:57 PM
                    0 responses
                    8 views
                    0 likes
                    Last Post DJ888
                    by DJ888
                     
                    Started by MacDad, 02-25-2024, 11:48 PM
                    7 responses
                    160 views
                    0 likes
                    Last Post loganjarosz123  
                    Working...
                    X