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?
#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

Comment