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

A boolean in OnBarUpdate() can not be called in OnRender()

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

    A boolean in OnBarUpdate() can not be called in OnRender()

    Hello!

    I have a piece of code in onbarUpdate() including a boolean. The idea is to save the bool value in OnBarUpdate() and to call it in OnRender() to draw a rectangle. The problem is that the conmpilation goes well, but when I attach the indicator on the chart, the rectangle is not drown. To check if the function works, I have replaced the boolean in OnBarUpdate() by Draw.Arrow() and I have the arrows on the chart. OnRender() is not involved for drawing arrows. Here is the piece of code:

    HTML Code:
    private bool flagUp = false;
    protected override void OnBarUpdate()
    {
       if(myFastEMACrossesAbovemySlowEMA)
       {
          flagUp = true;
       }
       else if(myFastEMACrossesBelowmySlowEMA)
       {
         flagUp = false;
       }
    }
    HTML Code:
    protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
    {
      if (IsInHitTest) return;
      else base.OnRender(chartControl, chartScale);
    
      if(flagUp = true)
      {
         RenderTarget.FillRectangle(rect, UpColorBrushDx);
      }
    }​
    I would really appreciate if someone could point out what is going wrong.

    Many thanks in advance!
    Last edited by Stanfillirenfro; 01-08-2024, 08:49 AM.

    #2
    Hello Stanfillirenfro,

    Thank you for your post.

    You should be able to access the bool that is set in OnBarUpdate() from within OnRender(). Please add print statements to help with debugging your script's behavior, and also check for any error messages in the Log tab of the Control Center. For more information on using Prints to debug:


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

    Comment


      #3
      Hello NinjaTrader_Emily for your reply.

      1) I have added the Print() in OnRender() including a simple operation:
      HTML Code:
      if(flagUp == true)
      {
          Print("Operation" + "   " + 2*4 + "  ");
        }​
      On the output window, there is NOTHING written.
      As I have mentioned in the post #1, taking both function separately they work fine independently. I can draw rectangle without the boolean in Onrender(). I can also draw arrows under the condition set in OnBarUpdate(). But when both functions are combined, the output window pups out NOTHING.

      Any idea? Any help?

      Thanks ina advance!

      Comment


        #4
        Originally posted by Stanfillirenfro View Post
        Hello NinjaTrader_Emily for your reply.

        1) I have added the Print() in OnRender() including a simple operation:
        HTML Code:
        if(flagUp == true)
        {
        Print("Operation" + " " + 2*4 + " ");
        }​
        On the output window, there is NOTHING written.
        As I have mentioned in the post #1, taking both function separately they work fine independently. I can draw rectangle without the boolean in Onrender(). I can also draw arrows under the condition set in OnBarUpdate(). But when both functions are combined, the output window pups out NOTHING.

        Any idea? Any help?

        Thanks ina advance!
        If there are no prints in the output, that means the bool is not a value of true OR that there are errors that prevented the script from hitting that piece of logic. Please add prints that show when the bool is changed to true/false as well. Here is an example based on the snippet you previously shared:
        Code:
        private bool flagUp = false;
        protected override void OnBarUpdate()
        {
        Print(Time[0] + " myFastEMACrossesAbovemySlowEMA: " + myFastEMACrossesAbovemySlowEMA + " myFastEMACrossesBelowmySlowEMA: " + myFastEMACrossesBelowmySlowEMA);
        if(myFastEMACrossesAbovemySlowEMA)
        {
        flagUp = true;
        Print(Time[0] + " myFastEMACrossesAbovemySlowEMA is true: " + myFastEMACrossesAbovemySlowEMA  + " flagUp true: " + flagUp);
        }
        else if(myFastEMACrossesBelowmySlowEMA)
        {
        flagUp = false;
        Print(Time[0] + " myFastEMACrossesBelowmySlowEMA is true: " + myFastEMACrossesBelowmySlowEMA + " flagUp false: " + flagUp);
        }
        }​
        Thanks for your time and patience.
        Emily C.NinjaTrader Customer Service

        Comment


          #5
          Hello NinjaTrader_Emily for your reply.

          With the piece of code written in OnBarUpdate(), I have really NO PROBLEM. I have attached a file to show the arrows the code draws when the conditions are met. That means, the bool values should also be saved for further use in OnRender. I have the arrows under these conditions, but a huge problem in Onrender() with the values saved above.

          Please have a look on the attached file.

          Many thanks in advance!
          Attached Files
          Last edited by Stanfillirenfro; 01-08-2024, 10:49 AM.

          Comment


            #6
            Originally posted by Stanfillirenfro View Post
            Hello NinjaTrader_Emily for your reply.

            With the piece of code written in OnBarUpdate(), I have really NO PROBLEM. I have attached a file to show the arrows the code draws when the conditions are met. That means, the bool values should also be saved for further use in OnRender. I have the arrows under these conditions, but a huge problem in Onrender() with the values saved above.

            Please have a look on the attached file.

            many thanks in advance!
            OnRender() appears to only be set to draw when the bool is true. It could be the case that OnBarUpdate() is setting the bool to true then also back to false; in which case it would draw the object when true, but when set to false do you have a condition to remove all draw objects?


            Your test using Draw.Arrow() is not a 1:1 comparison and only prints can truly help to debug what is happening with OnRender() in your script. Please test out the suggested prints and let me know the results.

            I look forward to your reply with the results from the suggested prints so I may assist you with the next steps in the debugging process.
            Emily C.NinjaTrader Customer Service

            Comment


              #7
              Hello NinjaTrader_Emily!

              Thanks for your reply.

              I have attached the output of the Print() function according to your instructions.

              Have a look please!

              Thanks in advance!

              Attached Files

              Comment


                #8
                Originally posted by Stanfillirenfro View Post
                Hello NinjaTrader_Emily!

                Thanks for your reply.

                I have attached the output of the Print() function according to your instructions.

                Have a look please!

                Thanks in advance!
                Your output seems to indicate that the bool is being set to true. Next, you will need to debug the behavior from OnRender(). Is this snippet all that you currently have in OnRender()?
                Code:
                protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
                {
                if (IsInHitTest) return;
                else base.OnRender(chartControl, chartScale);
                
                if(flagUp = true)
                {
                RenderTarget.FillRectangle(rect, UpColorBrushDx);
                }
                }​​
                If so, you have not created the SharpDX.RectnalgeF rect struct as needed with a startPoint and endPoint, width, and height. Rendering shapes, such as Rectangles, is described on the following page:Otherwise, if you do have these values, please provide the full snippet of what you have in OnRender() so I may better understand and assist you.

                Thank you for your time and patience.
                Emily C.NinjaTrader Customer Service

                Comment


                  #9
                  NinjaTrader_Emily,
                  Is this snippet all that you currently have in OnRender()?
                  No, it isn't.

                  HTML Code:
                  protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
                  {
                    if (IsInHitTest) return;
                    else base.OnRender(chartControl, chartScale);
                  
                    SharpDX.Direct2D1.Brush areaBrushDx;
                    SharpDX.Direct2D1.Brush buyColorBrushDx;
                  
                    areaBrushDx         = areaBrush.ToDxBrush(RenderTarget);
                    buyColorBrushDx     = buyColorBrush.ToDxBrush(RenderTarget);
                  
                   SharpDX.Direct2D1.AntialiasMode oldAntialiasMode = RenderTarget.AntialiasMode;
                   RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.Aliased;​
                    
                    for(int index = ChartBars.FromIndex; index <= ChartBars.ToIndex; index++)
                    {
                      float xStart   = chartControl.GetXByBarIndex(ChartBars, index);
                      float yStart   = chartScale.GetYByValue(Close.GetValueAt(index));
                  
                       SharpDX.RectangleF rec   = new SharpDX.RectangleF(xStart, yStart, 5, 10);
                  
                      if(flagUp == true)
                      {
                          RenderTarget.FillRectangle(rec, buyColorBrushDx);​
                      }​
                  
                  
                      areaBrushDx.Dispose();
                      buyColorBrushDx.Dispose();​
                  }​​​

                  Comment


                    #10
                    Hello Stanfillirenfro,

                    Thanks for your reply.

                    Are there any error messages on the log tab of the Control Center? If not, please provide a reduced sample of the script that I may test on my end. It may be exported via the Control Center > Tools > Export > NinjaScript AddOn menu.

                    I appreciate your patience.
                    Emily C.NinjaTrader Customer Service

                    Comment


                      #11
                      Hello NinjaTrader_Emily for your reply.

                      Please find the reduced script as attached file.

                      Thanks in advance.
                      Attached Files

                      Comment


                        #12
                        Originally posted by Stanfillirenfro View Post
                        Hello NinjaTrader_Emily for your reply.

                        Please find the reduced script as attached file.

                        Thanks in advance.
                        Thanks for that example. I would like to compare your object rec with the rect example from the help guide. Here is what you have (as you previously shared):
                        Code:
                                    for(int index = ChartBars.FromIndex; index <= ChartBars.ToIndex; index++)
                                    {
                                        float xStart   = chartControl.GetXByBarIndex(ChartBars, index);
                                        float yStart = chartScale.GetYByValue(Close.GetValueAt(index));
                                        
                                        SharpDX.RectangleF rec   = new SharpDX.RectangleF(xStart, yStart, 5, 10);
                                        
                                        if(flagUp == true)
                                        {
                                            RenderTarget.FillRectangle(rec, buyColorBrushDx);
                                        }
                                    }
                                    
                                    areaBrushDx.Dispose();
                                    buyColorBrushDx.Dispose();​
                        Here is the example from the help guide:
                        Code:
                        // create two vectors to position the rectangle
                        
                        SharpDX.Vector2 startPoint = new SharpDX.Vector2(ChartPanel.X, ChartPanel.Y);
                        SharpDX.Vector2 endPoint = new SharpDX.Vector2(ChartPanel.X + ChartPanel.W, ChartPanel.Y + ChartPanel.H);
                         
                        
                        // calculate the desired width and heigh of the rectangle
                        float width = endPoint.X - startPoint.X;
                        float height = endPoint.Y - startPoint.Y;
                        
                         
                        
                        // define the brush used in the rectangle
                        
                        SharpDX.Direct2D1.SolidColorBrush customDXBrush = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.DodgerBlue);      
                        
                         
                        
                        // construct the rectangleF struct to describe the with position and size the drawing
                        SharpDX.RectangleF rect = new SharpDX.RectangleF(startPoint.X, startPoint.Y, width, height);
                        
                         
                        // execute the render target fill rectangle with desired values
                        RenderTarget.FillRectangle(rect, customDXBrush);
                        
                         
                        
                        // always dispose of a brush when finished
                        customDXBrush.Dispose();
                        If we compare the example's vectors to start/end the rectangle, startPoint and endPoint, with your xStart and yStart, there is a big difference. The vectors are x, y coordinates that represent the position of the top-left corner and bottom-right corner of the rectangle. This following page covers chart coordinates:


                        Your xStart is the value from GetXByBarIndex and yStart is GetYByValue which only gives you part of the needed coordinates. you also have a width of 5 and height of 10. The help guide example calculates the width by subtracting the start point's x value from the end point's x value and gets the height by subtracting the start point's y value from the end point's y value. This gives you the distance between the start and end coordinates to know the exact height and width needed to fill your rectangle. The section "SharpDX Vectors and Charting Coordinates" is also a helpful section to read in this case:


                        I was able to get a rectangle that fills the entire indicator panel with the following logic, which is a mix of the help guide example and your own:
                        Code:
                                    SharpDX.Direct2D1.Brush areaBrushDx;
                                    SharpDX.Direct2D1.Brush buyColorBrushDx;
                                    areaBrushDx         = areaBrush.ToDxBrush(RenderTarget);
                                    buyColorBrushDx     = buyColorBrush.ToDxBrush(RenderTarget);
                                    
                                    for(int index = ChartBars.FromIndex; index <= ChartBars.ToIndex; index++)
                                    {
                                        // create two vectors to position the rectangle
                        
                                        SharpDX.Vector2 startPoint = new SharpDX.Vector2(ChartPanel.X, ChartPanel.Y);
                                        SharpDX.Vector2 endPoint = new SharpDX.Vector2(ChartPanel.X + ChartPanel.W, ChartPanel.Y + ChartPanel.H);
                                        
                                        
                                        // calculate the desired width and heigh of the rectangle
                                        float width = endPoint.X - startPoint.X;
                                        float height = endPoint.Y - startPoint.Y;
                                        
                                        SharpDX.RectangleF rec = new SharpDX.RectangleF(startPoint.X, startPoint.Y, width, height);
                                        
                                        if(flagUp == true)
                                        {
                                            RenderTarget.FillRectangle(rec, buyColorBrushDx);
                                        }
                                    }
                                    
                                    areaBrushDx.Dispose();
                                    buyColorBrushDx.Dispose();​
                        You have implemented the best practices of only rendering on the visible area of the chart and also disposing of your brushes when finished. Now the start point, end point, width, and height just need to be adjusted to calculate and render the rectangle properly.

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

                        Comment


                          #13
                          Many thanks NinjaTrader_Emily for your reply.

                          I do not agree with you completely. Please have a look on the attached file.

                          My problem is not to draw rectangles, but to be able to do it under the boolean conditions set in OnBarUpdate(). My script is drowing rectangles without the boolean, but WHEN I have the boolean, I am expecting to have the rectangles drown only under this condition and therefore NOT on all bars for example when I have the bool == true.

                          The problem is the boolean set in OnBarUpdate() that I am failing to call in OnRender().

                          I would really appreciate if you could get concentrated only on the call of boolean in OnRender().

                          Many thanks in advance!
                          Attached Files

                          Comment


                            #14
                            Hello Stanfillirenfro,

                            Thank you for your reply.

                            The way you currently have it set up, the rectangle will draw when the bool is true and it will not draw when the bool is false. You can test this by commenting out your current conditions that toggle flagUp and manually set it to true or false:
                            Code:
                            //           Print(Time[0] + " myFastEMACrossesAbovemySlowEMA: " + CrossAbove(EMA(10), EMA(20), 5) + " myFastEMACrossesBelowmySlowEMA: " + CrossAbove(EMA(10), EMA(20), 5));
                            //            if(CrossAbove(EMA(10), EMA(20), 5))
                            //            {
                            //                Draw.ArrowUp(this, "ArrowUp"+CurrentBar, true, Time[0], Low[0] - 5*TickSize, BuyColorBrush);
                            //                flagUp = true;
                            //                Print(Time[0] + " myFastEMACrossesAbovemySlowEMA is true: " + CrossAbove(EMA(10), EMA(20), 5)  + " flagUp true: " + flagUp);
                            //            }
                            //            if(CrossBelow(EMA(10), EMA(20), 5))
                            //            {
                            //                Draw.ArrowDown(this, "ArrowDn"+CurrentBar, true, Time[0], High[0] + 5*TickSize, AreaBrush);
                            //                flagUp = false;
                            //                Print(Time[0] + " myFastEMACrossesBelowmySlowEMA is true: " + CrossBelow(EMA(10), EMA(20), 5) + " flagUp false: " + flagUp);
                            //            }              
                                        flagUp = true;​
                            or
                            Code:
                            //           Print(Time[0] + " myFastEMACrossesAbovemySlowEMA: " + CrossAbove(EMA(10), EMA(20), 5) + " myFastEMACrossesBelowmySlowEMA: " + CrossAbove(EMA(10), EMA(20), 5));
                            //            if(CrossAbove(EMA(10), EMA(20), 5))
                            //            {
                            //                Draw.ArrowUp(this, "ArrowUp"+CurrentBar, true, Time[0], Low[0] - 5*TickSize, BuyColorBrush);
                            //                flagUp = true;
                            //                Print(Time[0] + " myFastEMACrossesAbovemySlowEMA is true: " + CrossAbove(EMA(10), EMA(20), 5)  + " flagUp true: " + flagUp);
                            //            }
                            //            if(CrossBelow(EMA(10), EMA(20), 5))
                            //            {
                            //                Draw.ArrowDown(this, "ArrowDn"+CurrentBar, true, Time[0], High[0] + 5*TickSize, AreaBrush);
                            //                flagUp = false;
                            //                Print(Time[0] + " myFastEMACrossesBelowmySlowEMA is true: " + CrossBelow(EMA(10), EMA(20), 5) + " flagUp false: " + flagUp);
                            //            }              
                                        flagUp = false;​
                            OnRender() is able to detect if the bool is true or false, so the bool is not the condition. Am I understanding that you want only certain bars to be colored? Please clarify what you mean - originally you said that, "when I attach the indicator on the chart, the rectangle is not drown" and now you are saying that, "My script is drowing rectangles without the boolean"
                            Are you expecting only certain rectangles to be drawn? You would need to calculate which bars those rectangles should be drawn for and calculate the coordinates on the chart accordingly.

                            I look forward to your clarification.
                            Emily C.NinjaTrader Customer Service

                            Comment


                              #15
                              NinjaTrader_Emily, thanks for your reply.

                              Am I understanding that you want only certain bars to be colored?
                              No, all bars should be colored:
                              1. When the fast EMA crosses above the slow EMA, the bars should be colored, let's say in blue.
                              2. When the fast EMA crosses below the slow EMA, the bars should have another color, let's say in red.

                              "when I attach the indicator on the chart, the rectangle is not drawn" and now you are saying that, "My script is drowing rectangles without the boolean"
                              1. Without boolean called in OnRender(), I have the rectangles drawn and on all bars. I am sure that the function OnRender() is not the problem itself, since it draws rectangles.
                              2. But when the boolean is called in OnRender(), there is no rectagnles more drawn.

                              Are you expecting only certain rectangles to be drawn?
                              No, I am expecting all bars to have rectangles drawn on them, and their colors change when the fast EMA crosses above/below the slow EMA.

                              Thanks!

                              Comment

                              Latest Posts

                              Collapse

                              Topics Statistics Last Post
                              Started by AaronKoRn, Today, 09:49 PM
                              0 responses
                              2 views
                              0 likes
                              Last Post AaronKoRn  
                              Started by carnitron, Today, 08:42 PM
                              0 responses
                              8 views
                              0 likes
                              Last Post carnitron  
                              Started by strategist007, Today, 07:51 PM
                              0 responses
                              9 views
                              0 likes
                              Last Post strategist007  
                              Started by StockTrader88, 03-06-2021, 08:58 AM
                              44 responses
                              3,975 views
                              3 likes
                              Last Post jhudas88  
                              Started by rbeckmann05, Today, 06:48 PM
                              0 responses
                              9 views
                              0 likes
                              Last Post rbeckmann05  
                              Working...
                              X