Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Preventing Repeated Drawings in Fibonacci Indicator

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

    Preventing Repeated Drawings in Fibonacci Indicator

    Hi,

    My indicator detects outside bars and draws a Fibonacci retracement on the most recent one. However, the Fibonacci keeps redrawing excessively and seems to be stuck in a loop. How can I ensure it only draws once per valid outside bar and updates only when a new one forms?

    Also, I'm getting an Object reference not set to an instance of an object error. Could this be caused by accessing the DrawObjects collection too soon? What's the best way to handle this?

    -thanks

    #2
    Hello trdninstyle,

    Thank you for your post.

    How can I ensure it only draws once per valid outside bar and updates only when a new one forms?
    You would need to ensure your logic is only calling the draw method when your condition to detect an "outside bar" is true. If this isn't occurring as expected, I recommend debugging using prints so you can see how/when the condition is evaluating as true when you're not expecting it to.


    I'm getting an Object reference not set to an instance of an object error. Could this be caused by accessing the DrawObjects collection too soon? What's the best way to handle this?
    This error is indicating a variable was used that is null (meaning it has no value assigned). The variable is an object reference, in that when the variable is used, the object it is pointed to is returned.

    Checking for Null References - ninjatrader.com/support/helpGuides/nt8/checking_for_null_references.htm

    To determine what the source of the error is you will need to debug your strategy using print statements. I suggest you add a print statement every few lines of code and then observe the output window when you apply the strategy.

    The last print statement shown in the output window would indicate the error occurs after that print statement, you can then add further print statements to zero in on the offending code. After you find the exact object returning null, you could add a condition check in the script to check that the value is not null.
    Gaby V.NinjaTrader Customer Service

    Comment


      #3
      Hi Gaby,

      My indicator detects outside bars and draws a Fibonacci retracement on the latest one. When I toggle the Fibonacci OFF, it removes instantly (as expected). But when I toggle it back ON, I get this error:

      "Unhandled exception: 'barsAgo' needed to be between 0 and XXXX but was 1."

      I suspect it's trying to reference a bar that doesn't exist when redrawing the Fibonacci. What's the best way to ensure it safely redraws only on the most recent valid outside bar?

      Thanks!

      Comment


        #4
        Hello trdinstyle,

        It's hard to say how to address the error without seeing the code or the output.

        What line of code specifically is hitting this error? What is the index you are trying to access? What is the size of the collection? I recommend using prints to isolate which line is hitting the error, and the index that is trying to be accessed.
        Gaby V.NinjaTrader Customer Service

        Comment


          #5
          Hi Gaby,

          Issue with Fibonacci Drawing barsAgo Error & Repeating Drawings. The Fibonacci is working, but I am running into two key issues:
          1. The Fibonacci keeps redrawing excessively. << This did get fixed, sorry.
            • It should only draw on a newly detected outside bar, but it continues refreshing.
            • I attempted to track the last drawn outside bar using lastOutsideBarIndex, but it still triggers repeatedly. <<fixed
          2. I get the following error when toggling Fibonacci back ON:
            • This happens when I click the button to turn Fibonacci drawings back ON after turning them OFF.
            • It does not happen when turning it OFF.
            • The barsAgo value in my print statements always shows 0, yet I still get this error.
          3. Unhandled exception: 'barsAgo' needed to be between 0 and XXXX but was 1.

          Here is my full script:

          region Using declarations
          using System;
          using System.Collections.Generic;
          using NinjaTrader.NinjaScript;
          using NinjaTrader.NinjaScript.DrawingTools;
          using NinjaTrader.Gui.Tools;
          using System.Windows.Controls;
          using System.Windows.Media;
          using System.Windows;
          using NinjaTrader.Data;
          #endregion

          namespace NinjaTrader.NinjaScript.Indicators
          {
          public class MotherBarBO : Indicator
          {
          private bool drawFibonacci = true; // On/Off Toggle for Fibonacci
          private bool useHLToC = false; // Toggle HL to C vs HL to HL
          private int lastOutsideBarIndex = -1; // Track last outside bar
          private Button fibToggleButton;
          private Button onOffButton;
          private Grid chartGrid; // Stores the chart's grid reference

          protected override void OnStateChange()
          {
          if (State == State.SetDefaults)
          {
          Description = "Identifies Inside and Outside Bars with Fibonacci measurements.";
          Name = "MotherBarBO";
          Calculate = Calculate.OnBarClose;
          IsOverlay = true;
          }
          else if (State == State.DataLoaded)
          {
          ChartControl.Dispatcher.InvokeAsync(() => { AddButtons(); });
          }
          }

          private void AddButtons()
          {
          if (ChartControl == null || ChartControl.Parent == null)
          return;

          chartGrid = ChartControl.Parent as Grid;
          if (chartGrid == null)
          return;

          // Create HL Toggle Button
          fibToggleButton = new Button
          {
          Content = "HL to C: OFF",
          Background = Brushes.Red,
          Foreground = Brushes.White,
          Width = 80,
          Height = 30,
          Margin = new Thickness(10),
          HorizontalAlignment = HorizontalAlignment.Left,
          VerticalAlignment = VerticalAlignment.Top
          };
          fibToggleButton.Click += (s, e) =>
          {
          useHLToC = !useHLToC;
          fibToggleButton.Content = useHLToC ? "HL to C: ON" : "HL to C: OFF";
          fibToggleButton.Background = useHLToC ? Brushes.Green : Brushes.Red;
          Print("Button Clicked: HL to C is now " + (useHLToC ? "ON" : "OFF"));
          RefreshFibonacci();
          };

          // Create On/Off Button
          onOffButton = new Button
          {
          Content = "ON",
          Background = Brushes.Green,
          Foreground = Brushes.White,
          Width = 80,
          Height = 30,
          Margin = new Thickness(100, 10, 10, 10),
          HorizontalAlignment = HorizontalAlignment.Left,
          VerticalAlignment = VerticalAlignment.Top
          };
          onOffButton.Click += (s, e) =>
          {
          drawFibonacci = !drawFibonacci;
          onOffButton.Content = drawFibonacci ? "ON" : "OFF";
          onOffButton.Background = drawFibonacci ? Brushes.Green : Brushes.Red;
          Print("Button Clicked: Fibonacci Drawing is now " + (drawFibonacci ? "ON" : "OFF"));
          RefreshFibonacci();
          };

          // Add buttons to the chart panel UI
          if (!chartGrid.Children.Contains(fibToggleButton))
          chartGrid.Children.Add(fibToggleButton);
          if (!chartGrid.Children.Contains(onOffButton))
          chartGrid.Children.Add(onOffButton);
          }

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

          if (!drawFibonacci)
          {
          Print("Fibonacci Drawing is OFF, skipping drawing.");
          return;
          }

          // Detect Outside Bar
          bool isOutsideBar = High[0] > High[1] && Low[0] < Low[1];

          if (!isOutsideBar || lastOutsideBarIndex == CurrentBar)
          return; // Skip if not a new outside bar

          lastOutsideBarIndex = CurrentBar; // Update tracking

          bool isBullBar = Close[0] > Open[0];
          double fibHigh, fibLow;

          if (isBullBar)
          {
          fibLow = Low[0];
          fibHigh = useHLToC ? Close[0] : High[0]; // HL to C if button is ON
          }
          else
          {
          fibHigh = High[0];
          fibLow = useHLToC ? Close[0] : Low[0]; // HL to C if button is ON
          }

          string fibTag = "FibRetrace_" + CurrentBar;

          Print($"New Outside Bar Detected at Bar {CurrentBar}");
          Print($"Drawing Fibonacci for Bar {CurrentBar} - Low: {fibLow}, High: {fibHigh}");

          // Remove previous Fibonacci lines
          RemovePreviousFibonacci(fibTag);

          // Draw new Fibonacci
          DrawFibonacciRetracements(fibTag, fibLow, fibHigh, isBullBar);
          }

          private void DrawFibonacciRetracements(string fibTag, double low, double high, bool isBullBar)
          {
          string fibTemplate = isBullBar ? "Range Bar Thick BL" : "Range Bar Thick";

          int barsAgo = Math.Max(CurrentBar - lastOutsideBarIndex, 0); // Prevents negative barsAgo

          Print($"Attempting to draw Fibonacci - Tag: {fibTag}, Low: {low}, High: {high}, Template: {fibTemplate}");
          Print($"Debug: barsAgo before drawing = {barsAgo}, CurrentBar = {CurrentBar}, lastOutsideBarIndex = {lastOutsideBarIndex}");

          Draw.FibonacciRetracements(this, fibTag, false, barsAgo, high, barsAgo, low, false, fibTemplate);
          }

          private void RemovePreviousFibonacci(string currentFibTag)
          {
          List<string> tagsToRemove = new List<string>();

          foreach (var obj in DrawObjects.ToList()) // Convert to list before iterating
          {
          if (obj.Tag.StartsWith("FibRetrace_") && obj.Tag != currentFibTag) // Only remove previous ones
          tagsToRemove.Add(obj.Tag);
          }

          foreach (var tag in tagsToRemove)
          RemoveDrawObject(tag);
          }

          private void RefreshFibonacci()
          {
          if (!drawFibonacci)
          {
          Print("Clearing Fibonacci due to On/Off toggle.");
          RemovePreviousFibonacci(""); // Clear all Fibonacci drawings
          return;
          }

          Print("Refreshing Fibonacci based on current settings.");
          OnBarUpdate(); // Redraw Fibonacci immediately
          }
          }
          }

          I would appreciate any guidance on ensuring:
          • The Fibonacci only draws once per new outside bar.
          • The barsAgo issue is resolved when toggling Fibonacci back on.

          Thanks in advance!

          Best,
          trdninstyle
          Last edited by trdninstyle; 03-26-2025, 05:05 PM.

          Comment


            #6
            Hello trdinstyle,

            If you would like assistance, please debug the script using prints. First, you'll need to identify which line of code is hitting the error. I recommend you debug the script to narrow now exactly which line your code is hitting this error at.

            You can use prints, place a print every few lines with a new number: Print("1"); etc. That will help you see where the script gets in execution when you hit the error. Once you know what line throws the error its much easier to debug. After you have confirmed which line is throwing the error, you can add another print to then check which variable is hitting the index error.
            Gaby V.NinjaTrader Customer Service

            Comment


              #7
              Thank you,

              Here is my script applying more prints as you suggested, I ran it and going to apply these additional items: Not here, but I'm starting to reference what my Log says in Control Center.



              Full Script:

              region Using declarations
              using System;
              using System.Collections.Generic;
              using NinjaTrader.NinjaScript;
              using NinjaTrader.NinjaScript.DrawingTools;
              using NinjaTrader.Gui.Tools;
              using System.Windows.Controls;
              using System.Windows.Media;
              using System.Windows;
              using NinjaTrader.Data;
              #endregion

              namespace NinjaTrader.NinjaScript.Indicators
              {
              public class MotherBarBO : Indicator
              {
              private bool drawFibonacci = true; // On/Off Toggle for Fibonacci
              private bool useHLToC = false; // Toggle HL to C vs HL to HL
              private int lastOutsideBarIndex = -1; // Track last outside bar
              private Button fibToggleButton;
              private Button onOffButton;
              private Grid chartGrid; // Stores the chart's grid reference

              protected override void OnStateChange()
              {
              Print("OnStateChange() - State: " + State); // Debug print
              if (State == State.SetDefaults)
              {
              Print("Setting defaults...");
              Description = "Identifies Inside and Outside Bars with Fibonacci measurements.";
              Name = "MotherBarBO";
              Calculate = Calculate.OnBarClose;
              IsOverlay = true;
              }
              else if (State == State.DataLoaded)
              {
              Print("Data Loaded, adding buttons...");
              ChartControl.Dispatcher.InvokeAsync(() => { AddButtons(); });
              }
              }

              private void AddButtons()
              {
              Print("Adding buttons...");
              if (ChartControl == null || ChartControl.Parent == null)
              {
              Print("ChartControl or Parent is null. Exiting AddButtons.");
              return;
              }

              chartGrid = ChartControl.Parent as Grid;
              if (chartGrid == null)
              {
              Print("Chart grid is null. Exiting AddButtons.");
              return;
              }

              // Create HL Toggle Button
              fibToggleButton = new Button
              {
              Content = "HL to C: OFF",
              Background = Brushes.Red,
              Foreground = Brushes.White,
              Width = 80,
              Height = 30,
              Margin = new Thickness(10),
              HorizontalAlignment = HorizontalAlignment.Left,
              VerticalAlignment = VerticalAlignment.Top
              };
              fibToggleButton.Click += (s, e) =>
              {
              useHLToC = !useHLToC;
              fibToggleButton.Content = useHLToC ? "HL to C: ON" : "HL to C: OFF";
              fibToggleButton.Background = useHLToC ? Brushes.Green : Brushes.Red;
              Print("Button Clicked: HL to C is now " + (useHLToC ? "ON" : "OFF"));
              RefreshFibonacci();
              };

              // Create On/Off Button
              onOffButton = new Button
              {
              Content = "ON",
              Background = Brushes.Green,
              Foreground = Brushes.White,
              Width = 80,
              Height = 30,
              Margin = new Thickness(100, 10, 10, 10),
              HorizontalAlignment = HorizontalAlignment.Left,
              VerticalAlignment = VerticalAlignment.Top
              };
              onOffButton.Click += (s, e) =>
              {
              drawFibonacci = !drawFibonacci;
              onOffButton.Content = drawFibonacci ? "ON" : "OFF";
              onOffButton.Background = drawFibonacci ? Brushes.Green : Brushes.Red;
              Print("Button Clicked: Fibonacci Drawing is now " + (drawFibonacci ? "ON" : "OFF"));
              RefreshFibonacci();
              };

              // Add buttons to the chart panel UI
              if (!chartGrid.Children.Contains(fibToggleButton))
              chartGrid.Children.Add(fibToggleButton);
              if (!chartGrid.Children.Contains(onOffButton))
              chartGrid.Children.Add(onOffButton);
              }

              protected override void OnBarUpdate()
              {
              Print($"OnBarUpdate() - CurrentBar: {CurrentBar}");

              if (CurrentBar < 2)
              {
              Print("Skipping - Not enough bars yet.");
              return;

              }

              if (!drawFibonacci)
              {
              Print("Fibonacci Drawing is OFF, skipping drawing.");
              return;

              }

              // Detect Outside Bar
              bool isOutsideBar = High[0] > High[1] && Low[0] < Low[1];

              Print($"Checking Outside Bar Condition - High[0]: {High[0]}, High[1]: {High[1]}, Low[0]: {Low[0]}, Low[1]: {Low[1]}");
              if (!isOutsideBar || lastOutsideBarIndex == CurrentBar)

              {
              Print("Not a new outside bar, skipping.");
              return;

              }

              lastOutsideBarIndex = CurrentBar; // Update tracking
              Print($"New Outside Bar Detected at Bar {CurrentBar}");

              bool isBullBar = Close[0] > Open[0];
              double fibHigh, fibLow;

              if (isBullBar)
              {
              fibLow = Low[0];
              fibHigh = useHLToC ? Close[0] : High[0]; // HL to C if button is ON
              }
              else
              {
              fibHigh = High[0];
              fibLow = useHLToC ? Close[0] : Low[0]; // HL to C if button is ON
              }

              string fibTag = "FibRetrace_" + CurrentBar;

              Print($"Drawing Fibonacci for Bar {CurrentBar} - Low: {fibLow}, High: {fibHigh}");

              // Remove previous Fibonacci lines
              RemovePreviousFibonacci(fibTag);

              // Draw new Fibonacci
              DrawFibonacciRetracements(fibTag, fibLow, fibHigh, isBullBar);
              }

              private void DrawFibonacciRetracements(string fibTag, double low, double high, bool isBullBar)
              {
              string fibTemplate = isBullBar ? "Range Bar Thick BL" : "Range Bar Thick";

              int barsAgo = Math.Max(CurrentBar - lastOutsideBarIndex, 0); // Prevents negative barsAgo

              Print($"Attempting to draw Fibonacci - Tag: {fibTag}, Low: {low}, High: {high}, Template: {fibTemplate}");
              Print($"Debug: barsAgo before drawing = {barsAgo}, CurrentBar = {CurrentBar}, lastOutsideBarIndex = {lastOutsideBarIndex}");


              Draw.FibonacciRetracements(this, fibTag, false, barsAgo, high, barsAgo, low, false, fibTemplate);
              }

              private void RemovePreviousFibonacci(string currentFibTag)
              {
              Print("Removing previous Fibonacci drawings...");
              List<string> tagsToRemove = new List<string>();


              foreach (var obj in DrawObjects.ToList()) // Convert to list before iterating
              {
              Print($"Checking object: {obj.Tag}");
              if (obj.Tag.StartsWith("FibRetrace_") && obj.Tag != currentFibTag) // Only remove previous ones

              {
              Print($"Marking {obj.Tag} for removal.");
              tagsToRemove.Add(obj.Tag);

              }
              }

              foreach (var tag in tagsToRemove)
              {
              Print($"Removing Fibonacci object: {tag}");
              RemoveDrawObject(tag);

              }
              }

              private void RefreshFibonacci()
              {
              if (!drawFibonacci)
              {
              Print("Clearing Fibonacci due to On/Off toggle.");
              RemovePreviousFibonacci(""); // Clear all Fibonacci drawings
              return;

              }

              Print("Refreshing Fibonacci based on current settings.");
              OnBarUpdate(); // Redraw Fibonacci immediately

              }
              }
              }
              Last edited by trdninstyle; 03-27-2025, 09:47 AM.

              Comment


                #8
                Please attempt to debug the script. Without the output from debugging or letting us know which line is throwing the error we cannot assist further. Please also note that it is not within our support model to assist with scripts generated or checked by AI Tools.

                However we would be happy to provide insight for any direct specific inquiries you may have if you would like to create or debug this script yourself. Our support is able to assist with finding resources in our help guide as well as simple examples, and we are happy to provide guidance on how you can debug the script while running it on your machine. To start learning NinjaScript I would suggest the following link as a starting point.


                From our experience at this time, ChatGPT and other AI models are not adequate at generating valid NinjaScript code that function as the user has intended. We often find that these tools generate code that will call non-existent properties and methods, use improper classes or inheritance, and may have incorrect logic. Using these tools for general NinjaScript learning information may also provide incorrect responses. We highly encourage that you create a new NinjaScript yourself using the NinjaScript Editor and avoid any AI based coding tools.

                You can also contact a professional NinjaScript Consultant who would be eager to create or modify this script at your request or assist you with your script. The NinjaTrader Ecosystem has affiliate contacts who provide educational as well as consulting services. Please let me know if you would like a list of affiliate consultants who would be happy to create this script or any others at your request or provide one on one educational services.
                Gaby V.NinjaTrader Customer Service

                Comment


                  #9
                  Okay, I'll do the rest of the stuff on my own. Here's my output window. I can turn off the fib then I click to turn back on, and I get that pop up error.

                  Click image for larger version  Name:	2025-03-27 10_53_45-Chart - 5m ETH.png Views:	0 Size:	4.5 KB ID:	1338949

                  Click image for larger version

Name:	2025-03-27 10_59_21-Control Center - Log.png
Views:	32
Size:	43.3 KB
ID:	1338950

                  Checking object: Line 9125
                  Checking object: Line 9126
                  Checking object: Line 9128
                  Checking object: Line 9130
                  Checking object: Line 9131
                  Checking object: FibRetrace_6130
                  Marking FibRetrace_6130 for removal.
                  Checking object: Line 9133
                  Checking object: NinjaScriptInfo
                  Removing Fibonacci object: FibRetrace_6130
                  Button Clicked: Fibonacci Drawing is now ON
                  Refreshing Fibonacci based on current settings.
                  OnBarUpdate() - CurrentBar: 6137
                  Button Clicked: HL to C is now ON
                  Refreshing Fibonacci based on current settings.
                  OnBarUpdate() - CurrentBar: 6137
                  Button Clicked: HL to C is now OFF
                  Refreshing Fibonacci based on current settings.
                  OnBarUpdate() - CurrentBar: 6137
                  Last edited by trdninstyle; 03-27-2025, 09:00 AM.

                  Comment

                  Latest Posts

                  Collapse

                  Topics Statistics Last Post
                  Started by Mindset, Today, 12:46 AM
                  0 responses
                  3 views
                  0 likes
                  Last Post Mindset
                  by Mindset
                   
                  Started by moneymaster, Today, 12:38 AM
                  0 responses
                  3 views
                  0 likes
                  Last Post moneymaster  
                  Started by WilsonFoster, Yesterday, 11:35 PM
                  0 responses
                  8 views
                  0 likes
                  Last Post WilsonFoster  
                  Started by MiCe1999, Yesterday, 09:26 PM
                  0 responses
                  14 views
                  0 likes
                  Last Post MiCe1999  
                  Started by connorlmarble, Yesterday, 08:25 PM
                  0 responses
                  10 views
                  0 likes
                  Last Post connorlmarble  
                  Working...
                  X