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

Deadlocking NT8 BarsRequest

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

    Deadlocking NT8 BarsRequest

    NT8 BarsRequests fail to complete and or fail to update if an indicator's OnBarUpdate method takes a long time to complete.
    It seems like the entire update functionality of an NT8 bars request depends on all indicator OnBarUpdate methods completing quickly.

    Here's a "deadlock indicator" for you, along with a comment that shows how to "fix" the deadlock (until further complications arise, as explained below)

    Code:
    using NinjaTrader.Data;
    using NinjaTrader.Gui;
    using System.Threading;
    using System.Windows.Media;
    
    namespace NinjaTrader.NinjaScript.Indicators {
        public class DeadlockIndicator : Indicator {
    
            readonly ManualResetEvent DataLoaded = new ManualResetEvent(false);
    
            BarsRequest Request;
    
            protected override void OnStateChange() {
                switch (State) {
    
                    case State.SetDefaults:
                        IsOverlay = false;
                        AddPlot(new Stroke(Brushes.Orange), PlotStyle.Bar, "Value");
                        break;
    
                    case State.DataLoaded: {
                        Request = new BarsRequest(Instrument, Bars.FromDate, Bars.ToDate) {
                            TradingHours = TradingHours,
                            BarsPeriod = new BarsPeriod { BarsPeriodType = BarsPeriodType.Tick, Value = 1 },
                        };
                        Request.Request((_, errorCode, message) => {
                            DataLoaded.Set();
                        });
                        /// Uncommenting this line will "fix" the deadlock
                        /// by allowing the request to complete before the indicator starts processing OnBarUpdate events
                        //DataLoaded.WaitOne();
                        break;
                    }
    
                    case State.Terminated:
                        Request?.Dispose();
                        break;
                }
            }
    
            protected override void OnBarUpdate() {
                // Oops. Blocking the thread here prevents the bars request from completing.
                DataLoaded.WaitOne();
                // Do stuff with the data from the bars request
                Value[0] = 1;
            }
        }
    }
    Yes, I know that indicators can process data in a background thread and then use "TriggerCustomEvent" to fill in the historical plot values when it becomes available.
    But, I'm trying to make OnBarUpdate wait for the data to be available because 3rd party indicators, indicators that use my indicators, don't know about the asynchronous data and they want to be able to access my calculated values in the OnBarUpdate method.

    Yes, I know about adding additional data series to an indicator.
    But, My scenario's a bit more complex than that.

    Yes, By uncommenting the "fix" code shown in the example code above, I'm able to make the indicator work perfectly in historical-only situations because the thread is blocked in OnStateChange until the request is completed. Blocking a thread in OnStateChange appears not to affect bars requests, unlike OnBarUpdated.
    But, My "real" code doesn't use ManualResetEvents for blocking. It uses other logic to determine whether the background data processing has progressed far enough to allow OnBarUpdate to run for the current bar, and uses spin/sleep cycles to block OnBarUpdate until the data is ready.
    When the data feed is connected and new bars are forming, if any blocking is performed in OnBarUpdate, the bars request will get deadlocked and stop providing incoming data.

    Do you have any suggestions about how I can make my indicator compatible with 3rd-party indicators that expect data to be available in the OnBarUpdate method, whilst not deadlocking the bars requests?









    Last edited by bboyle1234; 02-20-2020, 07:54 AM.

    #2
    Hello bboyle1234,

    The DataLoaded.WaitOne(); is not supported by NinjaTrader. Waiting, sleeping, or otherwise halting a thread is not supported.

    BarsRequest data does not load in the the OnBarUpdate() method (which indicators and strategies override). Instead, real-time data received from a bars request has to be processed in a separate method assigned to the Update event.


    I am not aware of any way to make BarsRequest data available in the OnBarUpdate() method.

    Chelsea B.NinjaTrader Customer Service

    Comment

    Latest Posts

    Collapse

    Topics Statistics Last Post
    Started by habeebft, Today, 07:27 AM
    1 response
    11 views
    0 likes
    Last Post NinjaTrader_ChristopherS  
    Started by AveryFlynn, Today, 04:57 AM
    1 response
    12 views
    0 likes
    Last Post NinjaTrader_Erick  
    Started by Max238, Today, 01:28 AM
    4 responses
    37 views
    0 likes
    Last Post Max238
    by Max238
     
    Started by r68cervera, Today, 05:29 AM
    1 response
    10 views
    0 likes
    Last Post NinjaTrader_ChelseaB  
    Started by geddyisodin, Today, 05:20 AM
    1 response
    14 views
    0 likes
    Last Post NinjaTrader_Gaby  
    Working...
    X