Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Custom indicator to accept an NT8 indicator as Input

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

    Custom indicator to accept an NT8 indicator as Input

    Hello,

    I'm coding an indicator that provides indication if an oscillator is at a local extreme. In concept, it's fairly straightforward. When I apply the indicator to the oscillator indicator panel, it works well.

    However, when calling it from a strategy, I'm getting an index out of bounds error. Here's the indicator code:

    Code:
    public class MyIndicator: Indicator
    {
    private int lastUpdateBar;
    private Series<int> peaksValleysIndication;
    
    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    {
    Description = @"Provides an indication if an oscillator is at a local peak (1) or valley (-1). Otherwise, it's at zero (0).";
    Name = "MyIndicator";
    Calculate = Calculate.OnBarClose;
    IsOverlay = false;
    DisplayInDataBox = false;
    DrawOnPricePanel = false;
    PaintPriceMarkers = false;
    ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right;
    //Disable this property if your indicator requires custom values that cumulate with each new market data event.
    //See Help Guide for additional information.
    IsSuspendedWhileInactive = true;
    NumberBars = 40;
    BarsRequiredToPlot = NumberBars + 1;
    }
    else if (State == State.Configure) {
    peaksValleysIndication = new Series<int>(this);
    }
    else if (State == State.DataLoaded) {
    BarsRequiredToPlot = NumberBars + 1;
    }
    }
    
    protected override void OnBarUpdate()
    {
    
    if (CurrentBar < BarsRequiredToPlot) return;
    
    if (CurrentBar > lastUpdateBar) {
    
    //Print("Peaks and Valleys: O:" + Input[1] + " :: Highest:" + HighestBar(Input, NumberBars) + " Lowest: " + LowestBar(Input, NumberBars));
    
    peaksValleysIndication[0] = 0;
    
    int highestBar = HighestBar(Input, NumberBars);
    int lowestBar = LowestBar(Input, NumberBars);
    
    if (Input[0] >= Input[highestBar]) {
    Draw.ArrowDown(this, "Arrow" + CurrentBar, IsAutoScale, 1, Input[0] + SignalDrawOffset, DownArrowColor);
    peaksValleysIndication[0] = -1;
    }
    else if (Input[0] <= Input[lowestBar]) {
    Draw.ArrowUp(this, "Arrow" + CurrentBar, IsAutoScale, 1, Input[0] - SignalDrawOffset, UpArrowColor);
    peaksValleysIndication[0] = 1;
    }
    
    lastUpdateBar = CurrentBar;
    }
    
    }
    [HASHTAG="t3322"]region[/HASHTAG] Properties
    
    // Parameters
    
    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name = "Number of Bars", Description = "Number of bars to consider a valid peak or valley.", Order = 1, GroupName = "1. Parameters")]
    public int NumberBars { get; set; }
    
    // Settings
    
    [XmlIgnore]
    [Display(Name = "Arrow Up Color", Description = "Color for long signals.", GroupName = "2. Settings", Order = 1)]
    public Brush UpArrowColor { get; set; }
    
    [Browsable(false)]
    public string UpArrowColorSerialize {
    get { return Serialize.BrushToString(UpArrowColor); }
    set { UpArrowColor = Serialize.StringToBrush(value); }
    }
    
    [XmlIgnore]
    [Display(Name = "Arrow Down Color", Description = "Color for short signals.", GroupName = "2. Settings", Order = 2)]
    public Brush DownArrowColor { get; set; }
    
    [Browsable(false)]
    public string DownArrowColorSerialize {
    get { return Serialize.BrushToString(DownArrowColor); }
    set { DownArrowColor = Serialize.StringToBrush(value); }
    }
    
    [Browsable(false)]
    [XmlIgnore]
    public Series<int> PeaksValleysIndication {
    get { return peaksValleysIndication; }
    }
    
    [NinjaScriptProperty]
    [Range(0, double.MaxValue)]
    [Display(Name = "Signal Draw Offset", Description = "Value from the parent indicator to draw the arrows.", GroupName = "2. Settings", Order = 3)]
    public double SignalDrawOffset { get; set; }
    #endregion
    
    }
    }

    Here are the relevant parts of code the strategy:

    Code:
    public class MyStrategy : Strategy {
    
    private MyIndicator theInd;
    private RSI theRSI;
    
    protected override void OnStateChange() {
    if (State == State.DataLoaded) {
    theRSI = RSI(4, 3);
    ​theInd= MyIndicator(theRSI, 40, 8);
    }
    }
    protected override void OnBarUpdate() {
        if (IsFirstTickOfBar) {
             theInd.Update();
            int indVal = theInd[1];  // <<< ERROR: Index was outside the bounds of the array.
    
    if (indVal == 1) { ... }
    ​
    ​}
    
    }
    ​
    When debugging, Input[0] shows valid values between 0 and 100, typical for the RSI. So, my custom indicator is getting the right series from the oscillator, and it's setting the indication series as 0, -1, or 1 while stepping through the indicator code.

    However, when I try to reference the indication value in the strategy, I get the "Index was outside the bounds of the array." Also, when paused and looking at the indicator and its properties, the Value property shows the error in the VS Watch window.

    I get the same error in both Playback and live.

    I'm sure I'm missing something simple... A little help please!

    Thank you,
    Matt

    #2
    Hello StealthM93,

    Just to make sure this is not a simple bars ago error please try adding the following to the strategy:
    Code:
    protected override void OnBarUpdate() 
    {
    if(CurrentBar < 1) return; 
    // your code

    Comment


      #3
      Thanks, NinjaTrader_Jesse,

      While I didn't show that, that check is already in place. I'm starting the strategy with plenty of bars on the chart. Though I do notice, when debugging, that the indicator appears to be "resetting" itself by going through all the existing bars, from CurrentBar = 1 through CurrentBar = {number of bars on the chart}, WHEN the strategy is first asking of the peaksValleysIndication (that is, the int indVal = theInd[1]; call). I find that odd as that should be happening when the strategy is first enabled and the playback/chart "catches up" to the latest bar.

      Thanks,
      Matt

      Comment


        #4
        Hello StealthM93,

        The resetting is because you are using Update, that should not be required to access the series value. That is only required to be placed in public properties that are not series. Its possible that is causing some problem, try removing the Update and see if that allows it to work normally.

        Comment


          #5
          Thanks, NinjaTrader_Jesse,

          I added that since I was getting this behavior. So, this "Index was outside the bounds of the array." exception is being thrown regardless if the .Update() call is there. And, to your point, I'm not calling any property members, just the series. I'll remove it. But, the issue still remains.

          Any other thoughts?

          Thanks,
          Matt
          Last edited by StealthM93; 08-29-2024, 10:00 AM. Reason: Additional info

          Comment


            #6
            Hi NinjaTrader_Jesse,

            If I may, please let me send an email to support that will have my entire strategy attached. Please provide the necessary subject line to refer to this thread.

            Thanks,
            Matt

            Comment


              #7
              Hello StealthM93,

              Thank you for attaching the file, I will need to test this on my end to see what may be happening. Please do not send an email to support, you already have a case open in this thread which we will be happy to assist further. As long as the code provided demonstrates the issue what you provided is fine.

              Comment


                #8
                Okay, thanks, NinjaTrader_Jesse, I'm quite interested how you get the indicator to work.

                I made some adjustments to the code above, though, minor. I included some basic assignments for easier debugging and Print statement. During debug and dropping the indicator on the chart, the output of the Print is all correct.

                Also, for lines 48 and 55: BarsRequiredToPlot = NumberBars + 1;
                For some reason, even though the value is set on line 48 to 41, it gets reset to 20 when it arrives on line 55. After 55, BarsRequiredToPlot remains at 41.

                Attached Files
                Last edited by StealthM93; 08-29-2024, 06:22 PM.

                Comment


                  #9
                  Hi NinjaTrader_Jesse, just posting to let you know that I updated my previous post with the latest version of the indicator. The update is minor. It works really well on the chart, but I'm still getting the same error when used in a strategy. Any update sometime today would be great so that I can implement your recommendation and test in Playback over the weekend.

                  Thank you!
                  Matt

                  Comment


                    #10
                    Hello NinjaTrader_Jesse,

                    I discovered my issue. I was not setting values in the Value/Values series in the indicator. AND/OR Since I was setting values in a custom series, in my strategy, I was not calling the custom series.

                    All good... Thanks for the help!
                    Cheers,
                    Matt

                    Comment

                    Latest Posts

                    Collapse

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