Calculate ADR on chart bars in order to resolve inaccuracies with daily bars

This commit is contained in:
moshferatu 2024-03-12 08:10:59 -07:00
parent 515f444254
commit c96dc4aa8c

View File

@ -11,15 +11,10 @@ using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
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;
using NinjaTrader.Gui.PropertiesTest;
#endregion
//This namespace holds Indicators in this folder and is required. Do not change it.
@ -27,7 +22,8 @@ namespace NinjaTrader.NinjaScript.Indicators
{
public class DailyRange
{
public DateTime Date { get; set; }
public int StartBarIndex { get; set; }
public int EndBarIndex { get; set; }
public double UpperLevel { get; set; }
public double LowerLevel { get; set; }
}
@ -35,10 +31,12 @@ namespace NinjaTrader.NinjaScript.Indicators
public class ADR : Indicator
{
private const int PrimaryBars = 0;
private const int DailyBars = 1;
private TimeSpan SessionOpen;
private TimeSpan SessionClose;
private double CurrentDailyHigh = double.MinValue;
private double CurrentDailyLow = double.MaxValue;
private List<double> DailyHighs = new List<double>();
private List<double> DailyLows = new List<double>();
private List<DailyRange> DailyRanges = new List<DailyRange>();
@ -48,9 +46,8 @@ namespace NinjaTrader.NinjaScript.Indicators
{
Description = @"Average Daily Range (ADR)";
Name = "ADR";
Calculate = Calculate.OnBarClose;
Calculate = Calculate.OnPriceChange;
IsOverlay = true;
DrawOnPricePanel = true;
ScaleJustification = ScaleJustification.Right;
IsSuspendedWhileInactive = false;
@ -58,17 +55,6 @@ namespace NinjaTrader.NinjaScript.Indicators
ADRHighStroke = new Stroke(Brushes.Yellow, 3);
ADRLowStroke = new Stroke(Brushes.Yellow, 3);
}
else if (State == State.Configure)
{
AddDataSeries(Instrument.FullName, new BarsPeriod { BarsPeriodType = BarsPeriodType.Day, Value = 1 },
RangePeriod + 5, Bars.TradingHours.Name, Bars.IsResetOnNewTradingDay);
}
else if (State == State.DataLoaded)
{
SessionIterator chartSession = new SessionIterator(BarsArray[PrimaryBars]);
SessionOpen = chartSession.GetTradingDayBeginLocal(chartSession.ActualTradingDayExchange).TimeOfDay;
SessionClose = chartSession.GetTradingDayEndLocal(chartSession.ActualTradingDayExchange).TimeOfDay;
}
else if (State == State.Historical)
{
SetZOrder(-1); // Display behind bars on chart.
@ -77,22 +63,46 @@ namespace NinjaTrader.NinjaScript.Indicators
protected override void OnBarUpdate()
{
if (DailyBars != BarsInProgress || CurrentBar < RangePeriod)
if (PrimaryBars != BarsInProgress)
return;
if (Bars.IsFirstBarOfSession && IsFirstTickOfBar)
{
if (CurrentDailyHigh > double.MinValue)
{
DailyHighs.Add(CurrentDailyHigh);
DailyLows.Add(CurrentDailyLow);
}
double totalRange = 0;
for (int i = 0; i < RangePeriod; i++)
{
totalRange += Highs[DailyBars][i] - Lows[DailyBars][i];
if (DailyHighs.Count < RangePeriod)
return;
if (DailyRanges.Count > 0)
DailyRanges[DailyRanges.Count - 1].EndBarIndex = CurrentBar - 1;
double totalRange = 0;
for (int i = (DailyHighs.Count - 1); i >= (DailyHighs.Count - RangePeriod); i--)
totalRange += DailyHighs[i] - DailyLows[i];
double averageRange = totalRange / RangePeriod;
DailyRanges.Add(new DailyRange
{
StartBarIndex = CurrentBar,
UpperLevel = Close[1] + (averageRange / 2),
LowerLevel = Close[1] - (averageRange / 2),
});
CurrentDailyHigh = High[0];
CurrentDailyLow = Low[0];
}
double averageRange = totalRange / RangePeriod;
DailyRanges.Add(new DailyRange
else
{
Date = Time[0].Date.AddDays(1),
UpperLevel = Closes[DailyBars][0] + (averageRange / 2),
LowerLevel = Closes[DailyBars][0] - (averageRange / 2),
});
if (High[0] > CurrentDailyHigh)
CurrentDailyHigh = High[0];
if (Low[0] < CurrentDailyLow)
CurrentDailyLow = Low[0];
}
}
protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
@ -100,9 +110,9 @@ namespace NinjaTrader.NinjaScript.Indicators
base.OnRender(chartControl, chartScale);
foreach (var Range in DailyRanges)
{
int startX = ChartControl.GetXByTime(Range.Date.AddDays(-1).Add(SessionOpen));
int endX = ChartControl.GetXByTime(Range.Date.Add(SessionClose));
{
int startX = chartControl.GetXByBarIndex(ChartBars, Range.StartBarIndex);
int endX = Range.EndBarIndex == 0 ? ChartPanel.X + ChartPanel.W : chartControl.GetXByBarIndex(ChartBars, Range.EndBarIndex);
DrawHorizontalLine(startX, endX, chartScale.GetYByValue(Range.UpperLevel), ADRHighStroke);
DrawHorizontalLine(startX, endX, chartScale.GetYByValue(Range.LowerLevel), ADRLowStroke);