Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

When can I access ChartPanel?

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

    When can I access ChartPanel?

    I'm writing a small demo program to help me explore when various data items are available. Any attempt to access ChartPanel gets the following error message, regardless of State (I have tried access during Historical, Transition, and Realtime):

    Indicator 'Vsa_Demo_GetInformation': Error on calling 'OnStateChange' method: The calling thread cannot access this object because a different thread owns it.​
    All I am doing is trying to print ChartPanel.Name, just to establish that I can access it. Is there something I need to be careful of?

    #2
    Update: further testing shows ChartPanel is:
    • null in State=Configure
    • available in State=Dataloaded
    • thread problem from Historical onward
    I guess I have answered my own question: if you want to access it, do so in Dataloaded.

    Am I correct that Dataloaded is the only state where you can access it, or am I missing something?

    Comment


      #3
      The error "The calling thread cannot access this object because a different thread owns it" occurs when attempting to access a UI element from a thread that did not create it.
      I don't understand that ... note that it is a system object and, as my follow-up post said, I was able to access it in State=DataLoaded. My inability to access was from Historical onward. The facts that I could access it in DataLoaded and that it is a normal system object make me question whether ownership is the issue. What changed after my successful access in DataLoaded? Aren't indicators supposed to access it from Historical onward?

      Comment


        #4
        Thanks, Brandon. Is there a limitation on what the code I pass could be? The following code did not get a thread violation,but it also did not print anything. (Note: it was ChartPanel with the thread violation.

        Code:
        if(ChartPanel != null) {
             ChartPanel.Dispatcher.InvokeAsync(() => { DoPrint($"{ID}ChartPanel={ChartPanel}"); });
        }
        ​
        Last edited by ETFVoyageur; 05-20-2024, 04:20 PM.

        Comment


          #5
          Hello ETFVoyageur,

          Can you provide more details on what you are trying to accomplish with the ChartPanel object? The ChartPanel.Name is not documented so I am unsure if that would print anything. In the latest post you are printing a variable named ID and the ChartPanel object its self, that may not print anything if ChartPanel does not have a defined result for its ToString() method.



          The code you posted otherwise works to dispatch the code inside the dispatcher to the chart panel.

          Comment


            #6
            Hello ETFVoyageur,

            The ChartPanel is available in State.DataLoaded, State.Historical, and State.Realtime from OnStateChange() and after as this is when the script is running, and only if the ChartControl is not null (such as on the Strategies tab of the Control Center, Strategy Analyzer, or MarketAnalyzer).

            Use Print() to print to the NinjaTrader output window from an indicator.


            Try printing to check if the ChartPanel is null.
            if (ChartPanel == null)
            Print("Chart panel is null");

            A ChartControl.Dispatcher.InvokeAsync() is necessary as the UI runs on a different thread than the NinjaScript thread.

            Ownership would not be an issue.
            Chelsea B.NinjaTrader Customer Service

            Comment


              #7
              Jesse,

              Accomplish -- just a demo indicator for myself to explore what is available when.

              Information -- the exact same DoPrint() statement worked fine in State=Dataloaded. It printed:
              Code:
              (#4) Vsa_Demo_GetInformation:DataLoaded           ChartPanel=Panel: Index=0 #[B=1;I=5;S=0;D=0] min=401.861843636365 max=539.027429090889
              (​
              Lambda -- to avoid extraneous confusion I changed the line as follows and still got nothing printed:
              Code:
              ChartPanel.Dispatcher.InvokeAsync(() => { Print ("Got here"); });
              ​
              Chelsea,
              The ChartPanel is available in State.DataLoaded, State.Historical, and State.Realtime from OnStateChange()
              This is from State=Historical.

              and only if the ChartControl is not null (such as on the Strategies tab of the Control Center, Strategy Analyzer, or MarketAnalyzer).
              This is an indicator on a chart. Although not shown in the code I showed you, I did check for ChartControl being non-null. The code I did show you also checks for ChartPanel being non-null, and there is no problem calling its Dispatcher (other than the lambda not printing).

              Use Print() to print to the NinjaTrader output window from an indicator.
              I did. DoPrint() just checks a bool to see whether printing is enabled and then calls Print()

              Try printing to check if the ChartPanel is null.
              if (ChartPanel == null)
              Print("Chart panel is null");​
              I just added that and it is not null -- no surprise since it was not null in earlier states.

              A ChartControl.Dispatcher.InvokeAsync() is necessary as the UI runs on a different thread than the NinjaScript thread.
              I tried the print statement without the thread protection and got a thread violation. Jesse, earlier in this thread, was not surprised and suggested using the Dispatcher. I am just trying to understand why a simple Print statement does not work that way. ("{ Print ("Got here"); });")

              Comment


                #8
                Hello ETFVoyageur,

                Where are you executing that code from?

                I tried that code in State.Historical and see a Print, is it possible something is happening wrong in your custom DoPrint method?

                Code:
                else if (State == State.Historical)
                {
                    if(ChartPanel != null) {
                      ChartPanel.Dispatcher.InvokeAsync(() => { Print("Here"); });
                   }
                }​
                It is still not clear what your end goal is here for using ChartPanel, what are you trying to do with the ChartPanel? You may not need a dispatcher and may just need to approach the problem in a different way.

                The dispatcher is only needed if you are trying to access the ChartPanel from a different thread from which it resides, generally ChartPanel is not used at all from OnBarUpdate or OnStateChange but is referenced in OnRender for rendering purposes which does not require dispatching. For example the sample named " Using a static SharpDX Brush to render a rectangle on the chart panel"

                https://ninjatrader.com/support/help...8/onrender.htm

                Comment


                  #9
                  is it possible something is happening wrong in your custom DoPrint method?
                  The update I supplied, and is in the code sample you quote, uses just Print() precisely to avoid that concern. That still does not print.

                  It is still not clear what your end goal is here for using ChartPanel
                  My only goal is to explore what is available and when. If the answer is that accessing ChartPanel from Historical is not an approved usage, then fine. That would not cause me any problem; I just want to know.

                  I'm still curious why Print("Here") does not print, but that is nothing critical for me ... mainly curious because I am not used to async dispatch and its lambdas. An educational matter for me, not a business problem.
                  Last edited by ETFVoyageur; 05-21-2024, 01:14 PM.

                  Comment


                    #10
                    Hello ETFVoyageur,

                    I've tested the code Jesse has suggested and the print is appearing in the output window.

                    Below is a link to a video.


                    Attached is the test script.
                    ChartPanelDispatcherPrintTest_NT8.zip

                    Without modifying the test script, open the NinjaScript Output Window, then add the indicator to a chart.

                    Is the behavior different than what is shown in the video?
                    Chelsea B.NinjaTrader Customer Service

                    Comment


                      #11
                      Chelsea,

                      Thanks for all of your effort. I appreciate what you do.
                      • I watched the video and it does demonstrate the code working as it should.
                      • I imported your zip file, loaded it onto my chart, and that also works as it should.
                      • I cut-and-pasted your async line into my indicator, as you can see in the code below.
                      • You can also see that my own code line is exactly the same as yours, other than slightly different text.
                      Code:
                      else if (State == State.Historical)
                      {​
                      DoPrint($"{ID}ChartPanel is no longer directly available (thread violation) -- using async access");
                      ​if (ChartPanel != null) {
                           //ChartPanel.Dispatcher.InvokeAsync(() => { DoPrint($"{ID}ChartPanel={ChartPanel}"); });
                           Print($"{ID}Just before doing the dispatch");
                           ChartPanel.Dispatcher.InvokeAsync(() => { Print ("Got here"); });
                           ChartPanel.Dispatcher.InvokeAsync(() => { Print("Here"); });
                      }
                      else
                      {
                            DoPrint($"{ID}ChartPanel is null");
                      }
                      DoPrint($"{ID}Instrument={Instrument}");
                      ...
                      }
                      ​
                      The problem is that when I run it, I get the following.
                      Code:
                      (#4) Vsa_Demo_GetInformation:Historical           ChartPanel is no longer directly available (thread violation) -- using async access
                      (#4) Vsa_Demo_GetInformation:Historical           Just before doing the dispatch
                      (#4) Vsa_Demo_GetInformation:Historical           Instrument=SPY Default
                      ​
                      As you can see, the code got to the async statements, but I got no print from them.

                      If you have any suggestions, I'd like to hear them. Other than that, it looks like my problem and not yours. You have shown that the construct works. Now I need to figure out why not when put into my indicator. Any ideas?
                      Last edited by ETFVoyageur; 05-21-2024, 02:35 PM.

                      Comment


                        #12
                        Hello ETFVoyageur,

                        Is an issue with your custom method?

                        Try calling Print();
                        Chelsea B.NinjaTrader Customer Service

                        Comment


                          #13
                          Yes, I am using lots of Print() statements. As the output above shows, I print just before and after the async calls, but the async does not print. Since we know that the async code is correct (it works in your examples) my more complicated example must somehow be interfering.

                          I'll chase that down, but first I'm going to use SharpDX to address the fill issue we talked about in another thread.

                          Comment


                            #14
                            Mystery solved ... sort of ... I have not touched this indicator (I was fixing the bar numbers code in a different indicator). I just came back to this one and noticed that the printouts are happening fine now. I guess something must have gotten reinitialized, perhaps as a result of some NT restarts. I have no real explanation, but the code that mysteriously did not work now does work and I have not changed it.

                            Now that it prints the toy output I need to investigate the original problem.

                            [Later] I just checked and the original async printing also works. Nothing further to do now that all has mysteriously started working. My best guess remains reinitialization due to restarting.
                            Last edited by ETFVoyageur; 05-22-2024, 01:02 PM.

                            Comment

                            Latest Posts

                            Collapse

                            Topics Statistics Last Post
                            Started by Geovanny Suaza, 02-11-2026, 06:32 PM
                            0 responses
                            607 views
                            0 likes
                            Last Post Geovanny Suaza  
                            Started by Geovanny Suaza, 02-11-2026, 05:51 PM
                            0 responses
                            353 views
                            1 like
                            Last Post Geovanny Suaza  
                            Started by Mindset, 02-09-2026, 11:44 AM
                            0 responses
                            105 views
                            0 likes
                            Last Post Mindset
                            by Mindset
                             
                            Started by Geovanny Suaza, 02-02-2026, 12:30 PM
                            0 responses
                            560 views
                            1 like
                            Last Post Geovanny Suaza  
                            Started by RFrosty, 01-28-2026, 06:49 PM
                            0 responses
                            561 views
                            1 like
                            Last Post RFrosty
                            by RFrosty
                             
                            Working...
                            X