Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Paint Bar; Error on calling "OnStateChange" method: Index was outside...

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

    Paint Bar; Error on calling "OnStateChange" method: Index was outside...

    I have a super simple indicator, that NT will not create correctly. Not sure what I am doing wrong. I simply have a StochasticK indicator where I am trying to paint the bars green if it is over 85 and red if it is under 15. White if K is in-between 85-15. Below is the code, appreciate if someone can tell me what is wrong

    #region Using declarations
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Xml.Serialization;
    using NinjaTrader.Cbi;
    using NinjaTrader.Gui;
    using NinjaTrader.Gui.Chart;
    using NinjaTrader.Gui.SuperDom;
    using NinjaTrader.Data;
    using NinjaTrader.NinjaScript;
    using NinjaTrader.Core.FloatingPoint;
    using NinjaTrader.NinjaScript.DrawingTools;
    #endregion

    // This namespace holds indicators in this folder and is required. Do not change it.
    namespace NinjaTrader.NinjaScript.Indicators
    {
    /// <summary>
    /// The StochasticFast Oscillator using EMA instead of SMA.
    /// </summary>
    public class StochasticsColorBar : Indicator
    {
    private Series<double> den;
    private MAX max;
    private MIN min;
    private Series<double> nom;
    private EMA emaK;

    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    {
    Description = @"The StochasticFast Oscillator using EMA instead of SMA.";
    Name = "StochasticsColorBar";
    IsSuspendedWhileInactive = true;
    IsOverlay = true;
    IsChartOnly = true;
    PaintPriceMarkers = true;
    PeriodD = 5;
    PeriodK = 55;
    UpperLevel = 85;
    LowerLevel = 15;




    }
    else if (State == State.DataLoaded)
    {
    den = new Series<double>(this);
    nom = new Series<double>(this);
    min = MIN(Low, PeriodK);
    max = MAX(High, PeriodK);
    emaK = EMA(K, PeriodD);
    }
    }

    protected override void OnBarUpdate()
    {
    if(CurrentBar<30)
    return;

    double min0 = min[0];
    nom[0] = Close[0] - min0;
    den[0] = max[0] - min0;

    if (den[0].ApproxCompare(0) == 0)
    K[0] = CurrentBar == 0 ? 50 : K[1];
    else
    K[0] = Math.Min(100, Math.Max(0, 100 * nom[0] / den[0]));

    D[0] = emaK[0];

    if (PeriodK>UpperLevel)
    BarBrush = Brushes.Green;
    else if (PeriodK<LowerLevel)
    BarBrush = Brushes.Red;
    else
    BarBrush = Brushes.White;




    }


    #region Properties
    [Browsable(false)]
    [XmlIgnore()]
    public Series<double> D
    {
    get { return Values[0]; }
    }

    [Browsable(false)]
    [XmlIgnore()]
    public Series<double> K
    {
    get { return Values[1]; }
    }

    [Range(1, int.MaxValue), NinjaScriptProperty]
    [Display(ResourceType = typeof(Custom.Resource), Name = "PeriodD", GroupName = "NinjaScriptParameters", Order = 0)]
    public int PeriodD
    { get; set; }

    [Range(1, int.MaxValue), NinjaScriptProperty]
    [Display(ResourceType = typeof(Custom.Resource), Name = "PeriodK", GroupName = "NinjaScriptParameters", Order = 1)]
    public int PeriodK
    { get; set; }

    [Range(1, int.MaxValue), NinjaScriptProperty]
    [Display(ResourceType = typeof(Custom.Resource), Name = "Upper Level", GroupName = "NinjaScriptParameters", Order = 3)]
    public int UpperLevel
    { get; set; }

    [Range(1, int.MaxValue), NinjaScriptProperty]
    [Display(ResourceType = typeof(Custom.Resource), Name = "Lower Level", GroupName = "NinjaScriptParameters", Order = 4)]
    public int LowerLevel
    { get; set; }



    #endregion
    }
    }

    #2
    Hello EC_Chris,

    Thanks for the post.

    The custom DataSeries, K and D are used to draw the Plot of the Stochastics indicator, the public property getter for K an D returns this:

    Values[0]

    Since the Plots were deleted, the Values[][] array cannot accept any values.

    Adding these plots back to State.Configure fixes the code:

    Code:
    AddPlot(Brushes.DodgerBlue,NinjaTrader.Custom.Resource.StochasticsD);
    AddPlot(Brushes.Goldenrod,NinjaTrader.Custom.Resource.StochasticsK);
    pper);
    Please let us know if we may be of any further assistance.

    Comment


      #3
      Great thanks.
      But, how do I hide the stochastics so they don't plot?

      Right now they are plotting over the price

      Comment


        #4
        I spoke too soon.

        It is not fully working. it is only plotting the candles white. Think I need a plot added for the Upper and Lower level? ??

        Comment


          #5
          Hello,

          Thank you for your patience.

          To prevent any plots from drawing or scaling the chart, set the Brush colors to transparent and set IsOverLay and IsChartOnly to true, as you already have.


          Code:
          IsOverlay = true;
          IsChartOnly = true;
          
          AddPlot(Brushes.Transparent,NinjaTrader.Custom.Resource.StochasticsD);
          AddPlot(Brushes.Transparent,NinjaTrader.Custom.Resource.StochasticsK);
          AddLine(Brushes.Transparent,		20,	NinjaTrader.Custom.Resource.NinjaScriptIndicatorLower);
          AddLine(Brushes.Transparent,	80,	NinjaTrader.Custom.Resource.NinjaScriptIndicatorUpper);
          As for why the bars are only printing white, your condition is comparing values that never change.

          Code:
          PeriodD = 5;
          PeriodK = 55;
          UpperLevel = 85;
          LowerLevel = 15;
          
          if (PeriodK>UpperLevel) // 55>85 false
          BarBrush = Brushes.Green;
          else if (PeriodK<LowerLevel) 55 < 15 false
          BarBrush = Brushes.Red;
          else 
          BarBrush = Brushes.White;
          You might be thinking of the K and D plot. You can still use these values. If you want the current value of K or D, do this:

          Code:
          double myKvalue = K[0]; // or K[BarsAgo]
          double myDvalue = D[0]; // or D[BarsAgo]
          Please let us know if we may be of any further assistance.

          Comment

          Latest Posts

          Collapse

          Topics Statistics Last Post
          Started by Geovanny Suaza, 02-11-2026, 06:32 PM
          0 responses
          576 views
          0 likes
          Last Post Geovanny Suaza  
          Started by Geovanny Suaza, 02-11-2026, 05:51 PM
          0 responses
          334 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
          553 views
          1 like
          Last Post Geovanny Suaza  
          Started by RFrosty, 01-28-2026, 06:49 PM
          0 responses
          551 views
          1 like
          Last Post RFrosty
          by RFrosty
           
          Working...
          X