Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Thread Saftey for Indicator.State and other Properties

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

    Thread Saftey for Indicator.State and other Properties

    It is unclear from the documentation which properties are safe to access from multiple threads.

    Is Indicator.State thread safe or do I need to use Indicator.Dispatcher.Invoke/InvokeAsync to safely retrieve the state if I am accessing an indicator from an addon?

    #2
    Hello ntbone,

    Thank you for your post.

    You would not need to use a dispatcher to get the State property of an indicator. The State property is inherent to the indicator (or script). Invoking is necessary to access other threads, like the UI thread if planning to manipulate the WPF, which is not inherent to the script.

    That being said, all methods and properties in the NinjaTrader Help Guide listed under 'Indicator' or 'Strategy' could be used without invoking other threads.

    See the help guide documentation below for more information.
    NinjaScript Indicator methods and properties - https://ninjatrader.com/support/help.../indicator.htm
    NinjaScript Strategy methods and properties - https://ninjatrader.com/support/help...8/strategy.htm
    Multi-threading consideration for NinjaScript - https://ninjatrader.com/support/help...-threading.htm

    Let us know if we may assist further.
    <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

    Comment


      #3
      Are you saying they are thread safe then? Just because they are not on a UI thread and not actual UI doesn't make them thread safe. If I am accessing an indicator from a Addon, that indicator is running on a chart that chart will have its own UI thread, and the indicator will be running on the thread for the chart. My addon is running on a different UI thread therefore, to safely access Indicator.State property it either needs to
      1. Provide thread safe access
      2. Be accessed from the same thread that changes the properties state.
      One should never access data that can be changed by other threads without a synchronizing method to ensure safe thread access to the data. This is a fundamental thread safety principle.

      In this particular case the thread for the chart that has the indicator is the one changing the state of the indicator. I can only safely read the value from Indicator.State if my code is running in that same thread OR accesses to Indicator.State is internally thread safe. Since indicators have a dispatcher I am thinking that one way to safely access this value is using InvokeAsync from the indicators Dispatcher. Currently the only way I know which thread the indicator is running on is either to use the Indicator.Dispatcher or find the chart control that owns it and use its dispatcher.

      Why does an indicator even have a dispatcher when it doesn't have any UI?

      All if this is also assuming that indicators themselves are not spawned on different threads other then the chart control that owns them. I could see each indicator being allowed to run from a thread pool so as to speed up execution by evaluating multiple indicators simultaneously.

      Comment


        #4
        Hello ntbone,

        Thank you for your note.

        We do not have a list of which properties are in which thread or if a property is thread-safe and debugging steps may need to be taken when developing your Add-On. Since not everything runs on the same thread, a general rule of thumb is that if you receive a threading error when testing the Add-On, you would need to use a dispatcher to access that property in the Add-On.

        I would suggest checking the Log tab of the Control Center when testing your Add-On to verify if you receive a threading error or if everything is working properly in your script.

        Please let us know if we may assist further.
        <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

        Comment


          #5
          Debugging alone cannot safely determine whether an object is being accessed or changed by multiple threads or which thread it is being modified from. In this case I cannot verify when and who changes Indicator.State as I do not have access to the internals for the code base.

          Your general rule of thumb only works for WPF UI. The WPF framework specifically added checks to its properties and functions to ensure that when they are called they are being called from the UI thread to ensure thread safety. Other things like WPF binding are created thread safe, per the documentation.

          Generic C# code using threads won't throw errors if you modify a variable in Thread A while trying to read it simultaneously in thread B nor will it throw any sort of error if you try to modify something from multiple threads. Multi-threaded bugs caused by accessing or modifying data from multiple threads can be very difficult to track down and very hard to reproduce as they only show up when the correct conditions apply and are subject to many variables including how many cores the CPU has, how the scheduler works for the OS, the work load of the current computer and more. Race conditions do not have exceptions thrown when they occur nor do dead locks.

          When it comes to accessing non UI objects and non UI data its very unclear in NinjaTrader API what threads are involved with objects and whether they are thread safe. This documentation here



          further informs that functions like OnOrderUpdate(), OnExecutionUpdate() etc...are run on other threads. This would be another unsafe place to access various properties of an Indicator like Indicator.State.

          Further in the existing script code there are numerous locations where lock keyword is used on objects but no where in the documentation is it shown that this can be done and what objects can it be done on.

          Examples include

          @HeikenAshiBarsTypes.cs - lock(tradkingHours.Sessions).
          @APQ.cs - lock(SuperDom.MarketDepth.Instrument.SyncMarketDep th)

          and examples shared by NinjaTrader on the forum which include

          lock(Account.All)
          lock(Account.Positions)

          It would be dangerous, for example to iterate through Account.All collection without locking it first as some code in another thread could be adding to an Account while one is iterating through it.

          I have the same issue when dealing with Order object from unmanaged API. The documentation clearly states that information from orders can come from various worker threads yet its not clear that accessing the various properties of an order is thread safe. Reading properties from an Order object blindly without considering thread safety can lead to obscure hard to track down and reproduce bugs that won't show up in the Log or throw exceptions.

          Knowing which API's are thread safe and which one's aren't as well as which objects can be used for synchronization is important to writing thread safe code that wont suffer from deadlocks and race conditions and obscure bugs that will never show up in an event log or throw an exception.

          Comment


            #6
            Hello ntbone,

            Thank you for your note.

            Ultimately, it should be assumed that nothing is thread-safe.

            NinjaTrader has Thread Pools for historical data, Instrument threads for processing data, UI threads for UI work, and Adapter threads for OnOrderUpdate/OnExecutionUpdate/OnPositionUpdate work.

            NinjaTrader spawns multiple UI threads and Instrument threads. If you have 4 cores this means you'll have 4 UI threads and 4 instrument threads for a total of 8 threads. It spawns them per the number of logical processor cores detected on startup.

            Each time a window is opened it will randomly be assigned a UI thread on each startup, in windows a 'window' must be controlled and owned by a single UI thread. Any actions derived from that window are triggered by the UI thread that owns the window.

            Once a market data subscription is started, it is assigned an instrument thread randomly and all processes which are driven from realtime data for that instrument will be on the same instrument thread moving forward. The instrument thread will then drive logic

            Let us know if we may assist further.
            <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

            Comment


              #7
              Thanks for the extra info. Then if I want to access an Indicator's state to see what state it is in I need to do so in a thread safe manner. Can I use the Indicator's dispatcher to safely access an indicator?

              Comment


                #8
                Hello ntbone,

                Thank you for your note.

                That is correct. You could use a dispatcher to access an indicator's state. As a best practice, you should always make sure to use Dispatcher.InvokeAsync() to ensure your action is done asynchronously to any internal NinjaTrader actions. Calling the synchronous Dispatcher.Invoke() method can potentially result in deadlock scenarios as your script is loaded.

                See this help guide link for more information - https://ninjatrader.com/support/help...-threading.htm

                Please let us know if we may further assist.
                <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

                Comment


                  #9
                  With regards to the Order class from the unmanaged API, there is nothing that I am aware of to sync to the members in this class will be changed by whatever thread is responsible for handling updating the orders. Is this thread safe? If it isn't how does one access the members safely? It is never covered in any of the order API's but it does say that in order to get the latest information it is best to use the data from the Order instead of the data from the parameters to the various update functions.

                  Comment


                    #10
                    Great discussion. Thanks, ntbone and BrandonH.

                    Brandon, you mentioned that "Calling the synchronous Dispatcher.Invoke() method can potentially result in deadlock scenarios as your script is loaded.". Does this only apply at Load? For example, once an AddOn is loaded and actively in use, can Dispatcher.Invoke() be used without concern of deadlocks?

                    Thanks.
                    Multi-Dimensional Managed Trading
                    jeronymite
                    NinjaTrader Ecosystem Vendor - Mizpah Software

                    Comment


                      #11
                      Hello ntbone and jeronymite,

                      Thank you for your notes.

                      You would be able to directly reference members of an order object. Please note that if you are accessing Account.Orders, that collection should be locked before accessing it.

                      As described in the OnOrderUpdate() help guide page, the order object being passed is the most up-to-date order and the parameters of OnOrderUpdate() would follow the order in which those updates are received.

                      OnOrderUpdate() - https://ninjatrader.com/support/help...rderupdate.htm

                      Using Dispatcher.Invoke() does not only apply when the AddOn is loading and could cause deadlocks. Using Dispatcher.InvokeAsync() is recommended as per the Note section in the Help Guide documentation.

                      Multi-threading consideration for NinjaScript - https://ninjatrader.com/support/help...-threading.htm

                      Let us know if we may assist further.
                      <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

                      Comment


                        #12
                        So my understanding is Order object is thread safe.

                        Comment


                          #13
                          Hello ntbone,

                          Thank you for your post.

                          That is correct. Directly referencing members of an order object would be thread-safe.

                          Let us know if we may assist further
                          <span class="name">Brandon H.</span><span class="title">NinjaTrader Customer Service</span><iframe name="sig" id="sigFrame" src="/support/forum/core/clientscript/Signature/signature.php" frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 100%; height: 120px;"></iframe>

                          Comment

                          Latest Posts

                          Collapse

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