• If this is your first visit, you will have to register before you can post. To view messages, please scroll below and select the forum that you would like to visits. Questions? Be sure to check out the Forum FAQ.

Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Calling AddDataSeries on both a hosted and hosting Indicator

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

  • swcooke
    replied
    Thank you both so much. I was able to get it to work by using the tips given here in conjunction with making sure the GUEST Indicator explicitly returned a 0 when the GUEST was not set with some data yet.

    Leave a comment:


  • NinjaTrader_ChrisL
    replied
    Hi swcooke thanks for your reply.

    I was able to get this to work. You're never filling your public series so the indicator calling it can not see the series.

    Code:
    public class SampleLastEveryTick : Indicator
        {
            //public Series<double> sjClose;
            private double close;
            private int activeBar = 0;
    
            protected override void OnStateChange()
            {
                if (State == State.SetDefaults)
                {
                    Description                = "Test Indicatro";
                    Name                    = "SampleLastEveryTick";
                    BarsRequiredToPlot        = 0;
                    Calculate                = Calculate.OnEachTick;
                    DrawOnPricePanel        = false;
                    IsOverlay                = false;
                    DisplayInDataBox        = true;
                }
                else if(State == State.Configure){
                    AddDataSeries("MSFT");
                    sjClose    = new Series<double>(this);                
                }
            }
            protected override void OnMarketData(MarketDataEventArgs e)
            {
    
                if(BarsInProgress == 0)return;
                if(e.MarketDataType == MarketDataType.Last)
                {
                    close = e.Price;
                }
            }
            protected override void OnBarUpdate()
            {
                if(BarsInProgress != 0)return;
                if (CurrentBar < activeBar) //CurrentBar is -1
                    return;
    
                if (CurrentBar > activeBar)
                {
                    activeBar = CurrentBar;
                }
                sjClose[0] = close;
    
            }
    
            [Browsable(false)]
            [XmlIgnore]
            public Series<double> sjClose;
        }
    Also make sure your data feed is pulling in MSFT, pull up a MSFT chart and confirm you get historical and real time data.

    Please let me know if I can assist any further.

    Leave a comment:


  • MojoJojo
    replied
    OnBarUpdate() in the HOST is only invoked when HOST changes occur. Behind the scenes NT makes sure that the GUEST indicator is synchronized and processed first. So checking for GUEST updates should not be needed.

    With a second data input series there manual syncrhonization might be necessary, which was discussed here https://ninjatrader.com/support/foru...ther-indicator.

    Synchronization is a difficult problem, if you don't want to deal with the complexity, it is easier to duplicate the GUEST code in the HOST instead of using a GUEST indicator.
    Code duplication is undesirable, in case you're skilled enough you can move the logic of the GUEST to a third class and use it in the HOST and the GUEST.

    Another way would be to add a reference to the HOST to the GUEST indicator.

    Code:
    public class SampleLastEveryTick : Indicator {
            public CallBuySell HOST = null;
            ...
            protected override void OnBarUpdate() {
            ...
            if(HOST != null) HOST.process();

    Code:
        public class CallBuySell : Indicator {
        ...  
        else if (State == State.DataLoaded) {
            GUEST = SampleLastEveryTick();
            GUEST.HOST = this;
        }
        ...
        public void process() {
        }
    I don't know how that would turn out, but most likely it's more trouble than it is worth.
    Last edited by MojoJojo; 02-20-2020, 02:20 AM.

    Leave a comment:


  • swcooke
    replied
    Thanks MojoJojo,

    One follow up question. Is there any way to only process updates from my GUEST? Conceptually, something like this:

    Code:
    if(BarsInProgress == GUEST){
        //do stuff
    }
    In other words, how can I tell when OnBarUpdate is getting an update from GUEST and not the main bars array?

    Leave a comment:


  • MojoJojo
    replied
    Probably making sure that only the main data is being processed in the host is enough to get rid of the error.
    Code:
    if(BarsInProgress != 0)return;
    You can also check if the Guest indicator has enough data.
    Code:
    if (GUEST.CurrentBars[0] < 0)return;
    Maybe there is a proper way to ensure that data series are synchronized but after hours of debugging and finding out that in my case during State == State.Realtime the lower timeframe data series was lagging one bar behind on the OnBarUpdate event, I've given up on using multi timeframe guest indicators.

    As long as the logic isn't too complicated and you want to have both the host and the guest indicator, it is in my opinion best to move the logic to a helper class and use it instead of the guest indicator.
    Last edited by MojoJojo; 02-19-2020, 08:46 AM.

    Leave a comment:


  • swcooke
    replied
    Yes, it plots fine. I was careful in my post to point that out. The Indicator works well. I just can't call it. I can't see why the Print Statement would cause any issue but I commented it anyway and compiled and still see the error. I will take a look at the OrderFlow Indicator however, for the sake of seeing this with a really simple example, could you run my code and see if you are able to get it to work?

    Leave a comment:


  • NinjaTrader_ChrisL
    replied
    Hi swcooke, thanks for your note.

    It might be coming from this print in the SampleLastEveryTick indicator:
    Print(sjClose[1]); Does the SampleLastEveryTick indicator work on its own?

    A good example would be the OrderFlow indicators. Those indicators add a 1 tick series, therefore all indicators using an OrderFlow+ indicator need to add the 1 tick series as well.

    I look forward to hearing from you.

    Leave a comment:


  • Calling AddDataSeries on both a hosted and hosting Indicator

    I am reviewing the page about Multi-Time Frame and Instruments. Specifically, the section that talks about making sure you call AddDataSeries in State.Configure for both a hosting indicator and the hosted indicator. Is there an Indicator somewhere that best demonstrates how to do this? I have tried and can't seem to get it to work. Here is my host Indicator which is just supposed to provide the data for a hosting Indicator. Note that my issue is not with the data this indicator puts out. That is accurate. It's about calling it from a hosting indicator:

    Code:
        public class SampleLastEveryTick : Indicator
        {
            private Series<double> sjClose;
            private double close;
            private int activeBar = 0;
    
            protected override void OnStateChange()
            {
                if (State == State.SetDefaults)
                {
                    Description                = "Test Indicatro";
                    Name                    = "SampleLastEveryTick";
                    BarsRequiredToPlot        = 0;
                    Calculate                = Calculate.OnEachTick;
                    DrawOnPricePanel        = false;
                    IsOverlay                = false;
                    DisplayInDataBox        = true;
                }
                else if(State == State.Configure){
                    AddDataSeries("MSFT");
                    sjClose    = new Series<double>(this);                
                }
            }
            protected override void OnMarketData(MarketDataEventArgs e)
            {
                if(BarsInProgress == 0)return;
                if(e.MarketDataType == MarketDataType.Last)
                {
                    close = e.Price;
                }
            }
            protected override void OnBarUpdate()
            {
                if(BarsInProgress != 0)return;
                if (CurrentBar < activeBar) //CurrentBar is -1
                    return;
    
                if (CurrentBar > activeBar)
                {
                    Print(sjClose[1]);
                    activeBar = CurrentBar;
                }
                sjClose[0] = close;
            }
    
            [Browsable(false)]
            [XmlIgnore]
            public Series<double> SjClose
            {
                get {return sjClose;}
            }
        }
    And here is my attempt to call it from a hosting script:

    Code:
        public class CallBuySell : Indicator
        {
            SampleLastEveryTick GUEST = null;
            protected override void OnStateChange()
            {
                if (State == State.SetDefaults)
                {
                    Description                                    = @"Enter the description for your new custom Indicator here.";
                    Name                                        = "CallBuySell";
                    Calculate                                    = Calculate.OnEachTick;
                    IsOverlay                                    = false;
                    DisplayInDataBox                            = true;
                    DrawOnPricePanel                            = true;
                    DrawHorizontalGridLines                        = true;
                    DrawVerticalGridLines                        = true;
                    PaintPriceMarkers                            = true;
                    ScaleJustification                            = NinjaTrader.Gui.Chart.ScaleJustification.Right;
                    IsSuspendedWhileInactive                    = true;
                }
                else if(State == State.Configure){
    
                    AddDataSeries("MSFT");
                }
                else if (State == State.DataLoaded)
                {
                    GUEST = SampleLastEveryTick();
                }            
            }
            protected override void OnBarUpdate()
            {
                if (CurrentBar < 0)return;
                Print(GUEST.SjClose[0]);
            }
        }
    Lastly, here is the error I get when I add the hosting Indicator to a chart:
    Code:
    Error on calling 'OnBarUpdate' method on bar 0: You are accessing an index with a value that is invalid since it is out-of-range. I.E. accessing a series [barsAgo] with a value of 5 when there are only 4 bars on the chart.
    Last edited by swcooke; 02-18-2020, 04:40 PM.

Latest Posts

Collapse

Topics Statistics Last Post
Started by Wick Wrangler, Today, 12:42 AM
0 responses
6 views
0 likes
Last Post Wick Wrangler  
Started by Knortzsch, Today, 12:36 AM
0 responses
4 views
0 likes
Last Post Knortzsch  
Started by saltminer, Yesterday, 11:06 PM
0 responses
5 views
0 likes
Last Post saltminer  
Started by saltminer, Yesterday, 10:14 PM
0 responses
5 views
0 likes
Last Post saltminer  
Started by Mykro, Yesterday, 10:03 PM
0 responses
4 views
0 likes
Last Post Mykro
by Mykro
 
Working...
X