Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Innerbar Indicator unexpected behavior

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

    Innerbar Indicator unexpected behavior

    Hey,
    i am new to NinjaTrader development. I try to build an Indicator, that plots the following behavior:
    Iterate bars and check if a large Bar contains smaller bars. The condition for this is: If the open and close of one or multiple following bars of one "outer bar" is within the outer bars high and low, then its an innerbar.

    I want to print rectangles around the outer bar and the containing inner bars. With that approach, i want to check if the price is just "flowing" up and down a bit.

    The problem is that the following code does not work properly. I dont know exactly what the problem might be. I guess the problems source has to do with the CurrentBar. Like I said, iam new and try to understand how the system works right now.

    One example of the problem is, that iam nearly sure that the code is right and for my example chart, the result is: "outerbar index: 5" and "last innerbar index: 3". the rectangle should be printed from bar 5 to 3. those values are calculated and within the dictionary. But in the chart, the rectangle starte from 6 and ends at 4. so its not was I was expecting. And also iam very confused how the Bars and High, Low, Open, Close "Arrays" are filled. When i add the indicator to the chart, the Bars.Count is like 4.400. so... are there 4.400 bars present at the start?

    Code:
    #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.Gui.Tools;
    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
    {
        public class InnerBarsIndicator : Indicator
        {
            protected override void OnStateChange()
            {
                if (State == State.SetDefaults)
                {
                    Description = @"Enter the description for your new custom Indicator here.";
                    Name = "InnerBarsIndicator";
                    Calculate = Calculate.OnBarClose;
                    IsOverlay = true;
                    DisplayInDataBox = true;
                    DrawOnPricePanel = true;
                    DrawHorizontalGridLines = true;
                    DrawVerticalGridLines = true;
                    PaintPriceMarkers = true;
                    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;
                    AddPlot(new Stroke(Brushes.Orange, 2), PlotStyle.Square, "InnerBarRectangle");
                }
                else if (State == State.Configure)
                {
                }
            }
    
            protected override void OnBarUpdate()
            {
                if (CurrentBar < 30) return;
                RemoveDrawObjects();
    
                var innerBars = GetInnerBarModels(28);
                foreach (var item in innerBars)
                {
                    Draw.Rectangle(this, "tag" + item.Key.Index, item.Key.DateTime, High[item.Key.Index], item.Value.DateTime, Low[item.Key.Index], Brushes.Blue);
                }
            }
    
            public Dictionary<InnerBarModel, InnerBarModel> GetInnerBarModels(int lookbackCount)
            {
                var result = new Dictionary<InnerBarModel, InnerBarModel>();
                int currentOuterbar = lookbackCount;
                var currentOuterbarIndex = lookbackCount;
                for (int i = lookbackCount; i > 0; i--)
                {
    
                    if (IsInnerBar(currentOuterbar, i))
                    {
                        continue;
                    }
                    else
                    {
                        if (currentOuterbarIndex - i > 1)
                        {
                            result.Add(
                                new InnerBarModel() { DateTime = Time[currentOuterbarIndex], Index = currentOuterbar },
                                new InnerBarModel() { DateTime = Time[i], Index = i });
                        }
    
                        currentOuterbar = i;
                        currentOuterbarIndex = i;
                    }
                }
    
    
                return result;
            }
    
            private bool IsInnerBar(int currentOuterbar, int currentPriceItem)
            {
    
                var upperValue = Math.Max(Bars.GetOpen(currentPriceItem), Bars.GetClose(currentPriceItem));
                var lowerValue = Math.Min(Bars.GetOpen(currentPriceItem), Bars.GetClose(currentPriceItem));
    
                if (upperValue < Bars.GetHigh(currentOuterbar) && lowerValue > Bars.GetLow(currentOuterbar))
                {
                    return true;
                }
    
                return false;
            }
    
    
            #region Properties
    
            [Browsable(false)]
            [XmlIgnore]
            public Series<double> InnerBarRectangle
            {
                get { return Values[0]; }
            }
            #endregion
    
        }
        public class InnerBarModel
        {
            public DateTime DateTime { get; set; }
            public int Index { get; set; }
        }
    }
    
    #region NinjaScript generated code. Neither change nor remove.
    
    namespace NinjaTrader.NinjaScript.Indicators
    {
        public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
        {
            private InnerBarsIndicator[] cacheInnerBarsIndicator;
            public InnerBarsIndicator InnerBarsIndicator()
            {
                return InnerBarsIndicator(Input);
            }
    
            public InnerBarsIndicator InnerBarsIndicator(ISeries<double> input)
            {
                if (cacheInnerBarsIndicator != null)
                    for (int idx = 0; idx < cacheInnerBarsIndicator.Length; idx++)
                        if (cacheInnerBarsIndicator[idx] != null &&  cacheInnerBarsIndicator[idx].EqualsInput(input))
                            return cacheInnerBarsIndicator[idx];
                return CacheIndicator<InnerBarsIndicator>(new InnerBarsIndicator(), input, ref cacheInnerBarsIndicator);
            }
        }
    }
    
    namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
    {
        public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
        {
            public Indicators.InnerBarsIndicator InnerBarsIndicator()
            {
                return indicator.InnerBarsIndicator(Input);
            }
    
            public Indicators.InnerBarsIndicator InnerBarsIndicator(ISeries<double> input )
            {
                return indicator.InnerBarsIndicator(input);
            }
        }
    }
    
    namespace NinjaTrader.NinjaScript.Strategies
    {
        public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
        {
            public Indicators.InnerBarsIndicator InnerBarsIndicator()
            {
                return indicator.InnerBarsIndicator(Input);
            }
    
            public Indicators.InnerBarsIndicator InnerBarsIndicator(ISeries<double> input )
            {
                return indicator.InnerBarsIndicator(input);
            }
        }
    }
    
    #endregion
    ​

    #2
    Hello MysteriX,

    Welcome to the NinjaTrader forums!

    Bars.Count is the total number of bars (all of the bars that have loaded in historical, and then increases with each new realtime bar).

    CurrentBar is the bar currently processing in OnBarUpdate().

    To understand the behavior add debugging prints.

    Print the time of the bar and all values used in the condition that sets the plot value and the values used in the calculation for the plot value.

    Include labels for each value and comparison operator.

    Below is a link to a support article on using prints to understand behavior.
    Chelsea B.NinjaTrader Customer Service

    Comment

    Latest Posts

    Collapse

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