ninjatrader/indicators/OpeningRange.cs

274 lines
12 KiB
C#
Raw Normal View History

2023-02-10 16:39:29 +00:00
#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
public enum OpeningRangeBarType
{
Seconds,
Minutes,
Hours,
Volume
}
2023-02-10 16:39:29 +00:00
//This namespace holds Indicators in this folder and is required. Do not change it.
namespace NinjaTrader.NinjaScript.Indicators
{
2023-02-10 16:42:09 +00:00
public class OpeningRange : Indicator
{
private static int MINUTES_IN_HOUR = 60;
private static string REGULAR_TRADING_HOURS = "US Equities RTH";
private double OpeningRangeHigh;
private double OpeningRangeLow;
private double OpeningRangeMid;
private DateTime OpeningRangeDate;
private DateTime OpeningRangeStartTime;
private SessionIterator Session;
2023-02-10 16:42:09 +00:00
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
2023-02-10 16:44:14 +00:00
Description = @"Plots the user-defined opening range";
Name = "Opening Range";
Calculate = Calculate.OnPriceChange;
2023-02-10 16:44:14 +00:00
IsOverlay = true;
DisplayInDataBox = true;
DrawOnPricePanel = true;
DrawHorizontalGridLines = true;
DrawVerticalGridLines = true;
PaintPriceMarkers = true;
ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right;
2023-02-10 16:42:09 +00:00
//Disable this property if your indicator requires custom values that cumulate with each new market data event.
//See Help Guide for additional information.
2023-02-10 16:44:14 +00:00
IsSuspendedWhileInactive = true;
ArePlotsConfigurable = false;
OpeningRangePeriod = 30;
OpeningRangeType = OpeningRangeBarType.Minutes;
2023-02-10 16:42:09 +00:00
OpeningRangeHighStroke = new Stroke(Brushes.Yellow, DashStyleHelper.Solid, 3);
OpeningRangeLowStroke = new Stroke(Brushes.Yellow, DashStyleHelper.Solid, 3);
OpeningRangeMidStroke = new Stroke(Brushes.Gray, DashStyleHelper.Dash, 3);
AddPlot(Brushes.Transparent, "ORH");
AddPlot(Brushes.Transparent, "ORL");
AddPlot(Brushes.Transparent, "ORM");
}
else if (State == State.Configure)
{
OpeningRangeHigh = 0.0;
OpeningRangeLow = 0.0;
OpeningRangeMid = 0.0;
OpeningRangeDate = DateTime.MinValue;
OpeningRangeStartTime = DateTime.MinValue;
if (OpeningRangeType == OpeningRangeBarType.Volume)
{
AddDataSeries(Instrument.FullName, new BarsPeriod {
BarsPeriodType = BarsPeriodType.Volume, Value = OpeningRangePeriod }, REGULAR_TRADING_HOURS);
}
else if (OpeningRangeType == OpeningRangeBarType.Seconds)
{
AddDataSeries(Instrument.FullName, new BarsPeriod {
BarsPeriodType = BarsPeriodType.Second, Value = OpeningRangePeriod }, REGULAR_TRADING_HOURS);
}
else if (OpeningRangeType == OpeningRangeBarType.Hours)
{
AddDataSeries(Instrument.FullName, new BarsPeriod {
BarsPeriodType = BarsPeriodType.Minute, Value = OpeningRangePeriod * MINUTES_IN_HOUR }, REGULAR_TRADING_HOURS);
}
else
{
AddDataSeries(Instrument.FullName, new BarsPeriod {
BarsPeriodType = BarsPeriodType.Minute, Value = OpeningRangePeriod }, REGULAR_TRADING_HOURS);
}
2023-02-10 16:42:09 +00:00
}
else if (State == State.DataLoaded)
{
Session = new SessionIterator(BarsArray[1]);
}
2023-02-10 16:42:09 +00:00
}
protected override void OnBarUpdate()
{
DateTime now = Times[BarsInProgress][0];
DateTime marketOpen = now.Date + Session.GetTradingDayBeginLocal(Session.ActualTradingDayExchange).TimeOfDay;
DateTime marketClose = now.Date + Session.GetTradingDayEndLocal(Session.ActualTradingDayExchange).TimeOfDay;
if (now.Date != OpeningRangeDate)
{
OpeningRangeHigh = 0.0;
OpeningRangeLow = 0.0;
OpeningRangeMid = 0.0;
}
if (BarsInProgress == 0)
{
ORH[0] = OpeningRangeHigh;
ORL[0] = OpeningRangeLow;
OpeningRangeMid = (OpeningRangeLow + OpeningRangeHigh) / 2.0;
ORM[0] = OpeningRangeMid;
if (now > marketOpen && now.Date != OpeningRangeDate)
{
OpeningRangeStartTime = now;
OpeningRangeDate = now.Date;
}
if (OpeningRangeHigh > 0.0 && OpeningRangeLow > 0.0)
{
Draw.Line(this, "ORH@" + OpeningRangeHigh, true, OpeningRangeStartTime, OpeningRangeHigh, marketClose, OpeningRangeHigh,
OpeningRangeHighStroke.Brush, OpeningRangeHighStroke.DashStyleHelper, (int)OpeningRangeHighStroke.Width);
Draw.Line(this, "ORL@" + OpeningRangeLow, true, OpeningRangeStartTime, OpeningRangeLow, marketClose, OpeningRangeLow,
OpeningRangeLowStroke.Brush, OpeningRangeLowStroke.DashStyleHelper, (int)OpeningRangeLowStroke.Width);
Draw.Line(this, "ORM@" + OpeningRangeMid, true, OpeningRangeStartTime, OpeningRangeMid, marketClose, OpeningRangeMid,
OpeningRangeMidStroke.Brush, OpeningRangeMidStroke.DashStyleHelper, (int)OpeningRangeMidStroke.Width);
}
return;
}
2023-02-10 16:39:29 +00:00
if (Bars.IsFirstBarOfSession)
{
if (Highs[BarsInProgress][0] > OpeningRangeHigh || OpeningRangeHigh == 0.0)
2023-02-10 16:39:29 +00:00
{
2023-02-10 16:42:09 +00:00
RemoveDrawObject("ORH@" + OpeningRangeHigh);
RemoveDrawObject("ORM@" + OpeningRangeMid);
OpeningRangeHigh = Highs[BarsInProgress][0];
2023-02-10 16:42:09 +00:00
}
2023-02-10 16:39:29 +00:00
if (Lows[BarsInProgress][0] < OpeningRangeLow || OpeningRangeLow == 0.0)
2023-02-10 16:39:29 +00:00
{
2023-02-10 16:42:09 +00:00
RemoveDrawObject("ORL@" + OpeningRangeLow);
RemoveDrawObject("ORM@" + OpeningRangeMid);
OpeningRangeLow = Lows[BarsInProgress][0];
2023-02-10 16:42:09 +00:00
}
2023-02-10 16:39:29 +00:00
}
2023-02-10 16:42:09 +00:00
}
[NinjaScriptProperty]
[Range(1, int.MaxValue)]
[Display(Name = "Period", Description = "Opening range period", Order = 1, GroupName = "Parameters")]
public int OpeningRangePeriod
2023-02-10 16:42:09 +00:00
{ get; set; }
[NinjaScriptProperty]
[Display(Name = "Type", Description = "Type of opening range being calculated", Order = 2, GroupName = "Parameters")]
public OpeningRangeBarType OpeningRangeType
2023-02-10 16:42:09 +00:00
{ get; set; }
[NinjaScriptProperty]
[Display(Name = "Opening Range High", Description = "Opening range high line drawn on chart", Order = 3, GroupName = "Parameters")]
2023-02-10 16:42:09 +00:00
public Stroke OpeningRangeHighStroke
{ get; set; }
[NinjaScriptProperty]
[Display(Name = "Opening Range Low", Description = "Opening range low line drawn on chart", Order = 4, GroupName = "Parameters")]
2023-02-10 16:42:09 +00:00
public Stroke OpeningRangeLowStroke
{ get; set; }
[NinjaScriptProperty]
[Display(Name = "Opening Range Mid", Description = "Opening range mid line drawn on chart", Order = 5, GroupName = "Parameters")]
public Stroke OpeningRangeMidStroke
{ get; set; }
[Browsable(false)]
[XmlIgnore]
public Series<double> ORH
{
get { return Values[0]; }
}
[Browsable(false)]
[XmlIgnore]
public Series<double> ORL
{
get { return Values[1]; }
}
[Browsable(false)]
[XmlIgnore]
public Series<double> ORM
{
get { return Values[2]; }
}
2023-02-10 16:42:09 +00:00
}
2023-02-10 16:39:29 +00:00
}
#region NinjaScript generated code. Neither change nor remove.
namespace NinjaTrader.NinjaScript.Indicators
{
2023-02-10 16:42:09 +00:00
public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
{
private OpeningRange[] cacheOpeningRange;
public OpeningRange OpeningRange(int openingRangePeriod, OpeningRangeBarType openingRangeType, Stroke openingRangeHighStroke, Stroke openingRangeLowStroke, Stroke openingRangeMidStroke)
2023-02-10 16:42:09 +00:00
{
return OpeningRange(Input, openingRangePeriod, openingRangeType, openingRangeHighStroke, openingRangeLowStroke, openingRangeMidStroke);
2023-02-10 16:42:09 +00:00
}
public OpeningRange OpeningRange(ISeries<double> input, int openingRangePeriod, OpeningRangeBarType openingRangeType, Stroke openingRangeHighStroke, Stroke openingRangeLowStroke, Stroke openingRangeMidStroke)
2023-02-10 16:42:09 +00:00
{
if (cacheOpeningRange != null)
for (int idx = 0; idx < cacheOpeningRange.Length; idx++)
if (cacheOpeningRange[idx] != null && cacheOpeningRange[idx].OpeningRangePeriod == openingRangePeriod && cacheOpeningRange[idx].OpeningRangeType == openingRangeType && cacheOpeningRange[idx].OpeningRangeHighStroke == openingRangeHighStroke && cacheOpeningRange[idx].OpeningRangeLowStroke == openingRangeLowStroke && cacheOpeningRange[idx].OpeningRangeMidStroke == openingRangeMidStroke && cacheOpeningRange[idx].EqualsInput(input))
2023-02-10 16:42:09 +00:00
return cacheOpeningRange[idx];
return CacheIndicator<OpeningRange>(new OpeningRange(){ OpeningRangePeriod = openingRangePeriod, OpeningRangeType = openingRangeType, OpeningRangeHighStroke = openingRangeHighStroke, OpeningRangeLowStroke = openingRangeLowStroke, OpeningRangeMidStroke = openingRangeMidStroke }, input, ref cacheOpeningRange);
2023-02-10 16:42:09 +00:00
}
}
2023-02-10 16:39:29 +00:00
}
namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
{
2023-02-10 16:42:09 +00:00
public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
{
public Indicators.OpeningRange OpeningRange(int openingRangePeriod, OpeningRangeBarType openingRangeType, Stroke openingRangeHighStroke, Stroke openingRangeLowStroke, Stroke openingRangeMidStroke)
2023-02-10 16:42:09 +00:00
{
return indicator.OpeningRange(Input, openingRangePeriod, openingRangeType, openingRangeHighStroke, openingRangeLowStroke, openingRangeMidStroke);
2023-02-10 16:42:09 +00:00
}
public Indicators.OpeningRange OpeningRange(ISeries<double> input , int openingRangePeriod, OpeningRangeBarType openingRangeType, Stroke openingRangeHighStroke, Stroke openingRangeLowStroke, Stroke openingRangeMidStroke)
2023-02-10 16:42:09 +00:00
{
return indicator.OpeningRange(input, openingRangePeriod, openingRangeType, openingRangeHighStroke, openingRangeLowStroke, openingRangeMidStroke);
2023-02-10 16:42:09 +00:00
}
}
2023-02-10 16:39:29 +00:00
}
namespace NinjaTrader.NinjaScript.Strategies
{
2023-02-10 16:42:09 +00:00
public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
{
public Indicators.OpeningRange OpeningRange(int openingRangePeriod, OpeningRangeBarType openingRangeType, Stroke openingRangeHighStroke, Stroke openingRangeLowStroke, Stroke openingRangeMidStroke)
2023-02-10 16:42:09 +00:00
{
return indicator.OpeningRange(Input, openingRangePeriod, openingRangeType, openingRangeHighStroke, openingRangeLowStroke, openingRangeMidStroke);
2023-02-10 16:42:09 +00:00
}
public Indicators.OpeningRange OpeningRange(ISeries<double> input , int openingRangePeriod, OpeningRangeBarType openingRangeType, Stroke openingRangeHighStroke, Stroke openingRangeLowStroke, Stroke openingRangeMidStroke)
2023-02-10 16:42:09 +00:00
{
return indicator.OpeningRange(input, openingRangePeriod, openingRangeType, openingRangeHighStroke, openingRangeLowStroke, openingRangeMidStroke);
2023-02-10 16:42:09 +00:00
}
}
2023-02-10 16:39:29 +00:00
}
#endregion