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

force OnBarUpdate update

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

    force OnBarUpdate update

    OK -- here is my issue. How do I solve it?

    The user takes my menu choice to turn bar numbering on. Currently, I do that numbering in OnBarUpdate() because that seemed to me to be the logical place. The problem is that I don't know how to get my OnBarUpdate() to run in response to the user action. The numbering works fine if I manually force an update. I just don't know how to do that automatically.

    I don't care about OnBarUpdate(). I only care that I put numbers on the appropriate bars (e.g. every fifth bar) when the user tells me to. How do you suggest I get those numbers on the screen when the user tells me to?

    Thanks.

    #2
    Hello ETFVoyageur,

    I have moved this post into a separate thread since it was unrelated to the original thread. Please create a new thread when you want to discuss an unrelated topic. This will help us properly track each issue. Thanks for your understanding.

    OnBarUpdate() will only be called for a bar update or when Update() is called and a value needs to be updated. There is no way other way to force OnBarUpdate() to update.

    You could instead render the numbers on the bars from OnRender(). Then you could use ForceRefresh() if necessary to force the chart visual to re-render.
    Gaby V.NinjaTrader Customer Service

    Comment


      #3
      Sorry ... I saw it as a continuing topic. You were discussing forcing an update with ForceRefresh() and I replied that does not cause an update for me.

      Comment


        #4
        Hello ETFVoyageur,

        To confirm, you want OnBarUpdate() to update, is this correct?

        Calling Update() would cause OnBarUpdate() to update, and only if a value needs to be updated.
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          I have seen this question raised several times, but I have not seen a solution. Here is my situation:
          • An indicator puts a dropdown menu in the chart toolbar.
          • A user clicks on the menu entry that toggles showing bar numbers.
          • The expectation is that the code that adds or removes bar numbers will be run immediately.
          • I do not know the best way to make that happen.
          Currently, the code is in OnBarUpdate() where it does the job bar-by-bar. That works fine when I manually do something that causes a redraw. The problem is that I do not know how the menu callback can make that happen. Neither ForceRefresh() nor Update() makes OnBarUpdate() get called.

          I have tried some variations of the SendKeys("{F5}") solution, but could not make that have any effect. Just a plain SendKeys("{F5}") does not do the job. I'd be interested if anyone can point to some sample code that does such a thing
          ​​
          I could call ForceRefresh() which causes a call to OnRender() and have OnRender() call a function that would also be called for the last bar of OnBarUpdate(). That function would walk the bars array doing its thing. I expect that might work but OnRender() is called often enough that this seems like a pretty heavy-handed solution.

          I could just call such a function from the menu item callback handler and also when processing the last bar in OnBarUpdate(). That might work. Is there any problem with doing that at a random time (whenever the user clicks the menu)? So far, this seems like the best solution, but I am hoping for a way to trigger running OnBarUpdate().

          Bottom line: what is the best way to get the bar numbering code run so the user gets a prompt response?

          Comment


            #6
            Hello ETFVoyageur,

            "A user clicks on the menu entry that toggles showing bar numbers.
            The expectation is that the code that adds or removes bar numbers will be run immediately.​"

            Are you referring to the MenuItem.Click event with an event handler.

            Do you have a print to show that this event hander method is not running on the click event?

            What code is being run in this event handler method to add or remove bar numbers?
            Is this setting a bool to turn on / off logic in OnRender()?
            Is this a loop calling Draw.Text() / RemoveDrawObject() for all of the previous bars from 0 to current bar?


            How is this related to the logic in OnBarUpdate()? OnBarUpdate() will only run if there is something to update. ForceRefresh() repaints the chart and re-triggers OnRender(). (Helpful when adding draw objects after calling TriggerCustomEvent() from a non-data-driven thread like a button click)

            "Bottom line: what is the best way to get the bar numbering code run so the user gets a prompt response?"

            I'm assuming you are trying to custom render the bar number over each bar in OnRender().

            In the .Click event:
            Code:
            private void MyMenuItem_Click(object sender, RoutedEventArgs e)
            {
            renderBarNumbers = !renderBarNumbers;
            ForceRefresh();
            }

            In OnRender():
            Code:
            if (renderBarNumbers)
            {
            for (int index = ChartBars.FromIndex; index < ChartBars.ToIndex; index++)
            {
            float x = ChartControl.GetXByBarIndex(ChartBars, index) - (float)(ChartControl.Properties.BarDistance / 2);
            float y = chartScale.GetYByValue(Bars.GetLow(index));
            float w = 30;
            float h = 20;
            RenderTarget.DrawText(index.ToString(), textFormat, new SharpDX.RectangleF(x, y, w, h), ChartControl.Properties.ChartText.ToDxBrush(Render Target));
            }
            }​
            Chelsea B.NinjaTrader Customer Service

            Comment


              #7
              The menu callback is getting called. No problem with that.

              I put the code on OnBaarUdate() because that seemed like an obvious place. I realized only afterward that there seems to be no way to force OnBarUpdate() to run.

              As to the rendering, the code is pretty simple:
              Code:
              if (CurrentBar % BarFrequency != 0) return;    // Skip some of the bar numbers so the drawn ones are readable
                          
              if (ShowBarNumbersEnabled) {
                   double y = (BarNumberPlacement == LocalEnum.vsaBarNumberPlacement.Above)
                                  ? High[0] + TickSize * BarNumberOffset
                                  : Low[0] - TickSize * BarNumberOffset;
                   Draw.Text(this, BarNumbersTag+CurrentBar, CurrentBar.ToString(), 0, y, BarNumberColor);
              }
              ​
              As noted in the post you are replying to, I am wondering whether OnBarUpdate() is the wrong place to be doing this. Should I be doing it in OnRender() or is that called too often? Another alternative would be to do it in a function called from the menu callback and from OnBarUpdate() when processing the final bar. Is there any reason NT would care about for choosing one solution or the other? They should be equally easy to implement.





              Comment


                #8
                Chelsea,

                On reflection, it sounds to me as if you are saying that OnRender() is the best way to go. I have implemented code based on your suggestion and, unsurprisingly, it is working well. Thank you.

                Comment


                  #9
                  Hello ETFVoyageur,

                  Unfortunately, no information was provided about what code was being used to draw the bar numbers.

                  Code in OnBarUpdate(), which updates as the building bar updates, doesn't make sense. You could have been using a loop in the click handler event to call Draw methods or RemoveDrawObject (or loop through the DrawObjects collection to modify existing objects) after calling TriggerCustomEvent, or you could have been custom rendering.

                  I'm not clear on what code was in OnBarUpdate() that would be affected by a button click.

                  Chelsea B.NinjaTrader Customer Service

                  Comment


                    #10
                    That's old history now. I have taken your advice and am doing it from OnRender. I can envision alternatives, but since you are recommending OnRender() that's good enough for me.

                    Comment

                    Latest Posts

                    Collapse

                    Topics Statistics Last Post
                    Started by JackyP, 07-25-2023, 08:39 AM
                    3 responses
                    317 views
                    0 likes
                    Last Post Lancer
                    by Lancer
                     
                    Started by TiffanyMiller, Yesterday, 10:19 PM
                    0 responses
                    5 views
                    0 likes
                    Last Post TiffanyMiller  
                    Started by algospoke, 05-13-2024, 06:53 PM
                    12 responses
                    138 views
                    0 likes
                    Last Post algospoke  
                    Started by psangram, Yesterday, 06:35 PM
                    0 responses
                    6 views
                    0 likes
                    Last Post psangram  
                    Started by Alaina19, 07-14-2024, 04:38 PM
                    2 responses
                    17 views
                    0 likes
                    Last Post Alaina19  
                    Working...
                    X