#region Using declarations using NinjaTrader.Cbi; using NinjaTrader.Gui; using NinjaTrader.Gui.Chart; using NinjaTrader.Gui.Tools; using NinjaTrader.Data; using SharpDX.DirectWrite; using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Globalization; using System.Windows.Media; using System.Xml.Serialization; #endregion namespace NinjaTrader.NinjaScript.Indicators { public class OR { public double High { get; set; } public double Low { get; set; } public double Mid { get; set; } public double LatestPrice { get; set; } public DateTime StartTime { get; set; } public DateTime EndTime { get; set; } } [CategoryOrder("Opening Range", 1)] [CategoryOrder("Appearance", 2)] [CategoryOrder("Labels", 3)] [TypeConverter("NinjaTrader.NinjaScript.Indicators.OpeningRangePropertyConverter")] public class OpeningRange : Indicator { public static int DefaultOpeningRangePeriod = 30; public static OpeningRangeBarType DefaultOpeningRangeType = OpeningRangeBarType.Minutes; public static bool DefaultEnableExtensions = false; public static int DefaultNumberOfExtensions = 3; public static double DefaultExtensionMultiplier = 0.5; public static OpeningRangeColorScheme DefaultOpeningRangeColorScheme = OpeningRangeColorScheme.Default; public static Stroke DefaultOpeningRangeStroke = new Stroke(Brushes.Yellow, DashStyleHelper.Solid, 3); public static Stroke DefaultOpeningRangeMidStroke = new Stroke(Brushes.Gray, DashStyleHelper.Dash, 2); public static Stroke DefaultPriceAboveStroke = new Stroke(Brushes.LimeGreen, DashStyleHelper.Solid, 3); public static Stroke DefaultPriceBelowStroke = new Stroke(Brushes.Red, DashStyleHelper.Solid, 3); public static Stroke DefaultPriceInsideStroke = new Stroke(Brushes.Yellow, DashStyleHelper.Solid, 3); public static Stroke DefaultExtensionStroke = new Stroke(Brushes.Yellow, DashStyleHelper.Solid, 1); public static SimpleFont DefaultOpeningRangeFont = new SimpleFont("Arial", 12); public static Brush DefaultOpeningRangeFontColor = Brushes.LightGray; public static bool DefaultShowLabels = false; public static string DefaultOpeningRangeHighLabel = "ORH @ {level}"; public static string DefaultOpeningRangeLowLabel = "ORL @ {level}"; public static string DefaultOpeningRangeMidLabel = "ORM @ {level}"; public static OpeningRangeLabelPosition DefaultOpeningRangeLabelPosition = OpeningRangeLabelPosition.Center; private const int PrimaryBars = 0; private int OpeningRangeBars; private int RegularTradingHoursBars; private const string RegularTradingHours = "US Equities RTH"; private TimeSpan RegularTradingHoursOpen; private TimeSpan SessionClose; private List OpeningRanges; private OR CurrentOpeningRange; private double OpeningRangeHigh; private double OpeningRangeLow; private double OpeningRangeMid; private double LastPrice; private const int LabelPadding = 5; private const string LevelFormatString = "{level}"; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Opening Range Indicator"; Name = "Opening Range"; Calculate = Calculate.OnPriceChange; IsOverlay = true; DisplayInDataBox = true; DrawOnPricePanel = true; DrawHorizontalGridLines = true; DrawVerticalGridLines = true; PaintPriceMarkers = true; ScaleJustification = ScaleJustification.Right; IsSuspendedWhileInactive = false; OpeningRangePeriod = DefaultOpeningRangePeriod; OpeningRangeType = DefaultOpeningRangeType; EnableExtensions = DefaultEnableExtensions; NumberOfExtensions = DefaultNumberOfExtensions; ExtensionMultiplier = DefaultExtensionMultiplier; ColorScheme = DefaultOpeningRangeColorScheme; OpeningRangeHighStroke = DefaultOpeningRangeStroke; OpeningRangeLowStroke = DefaultOpeningRangeStroke; OpeningRangeMidStroke = DefaultOpeningRangeMidStroke; PriceAboveStroke = DefaultPriceAboveStroke; PriceBelowStroke = DefaultPriceBelowStroke; PriceInsideStroke = DefaultPriceInsideStroke; ExtensionStroke = DefaultExtensionStroke; ShowLabels = DefaultShowLabels; OpeningRangeFont = DefaultOpeningRangeFont; OpeningRangeFontColor = DefaultOpeningRangeFontColor; OpeningRangeHighLabel = DefaultOpeningRangeHighLabel; OpeningRangeHighLabelPosition = DefaultOpeningRangeLabelPosition; OpeningRangeLowLabel = DefaultOpeningRangeLowLabel; OpeningRangeLowLabelPosition = DefaultOpeningRangeLabelPosition; OpeningRangeMidLabel = DefaultOpeningRangeMidLabel; OpeningRangeMidLabelPosition = DefaultOpeningRangeLabelPosition; ArePlotsConfigurable = false; AddPlot(Brushes.Transparent, "ORH"); AddPlot(Brushes.Transparent, "ORL"); AddPlot(Brushes.Transparent, "ORM"); } else if (State == State.Configure) { ResetOpeningRange(DateTime.MinValue); OpeningRanges = new List(); BarsPeriod openingRangeBarsPeriod = new BarsPeriod { BarsPeriodType = (BarsPeriod.BarsPeriodType == BarsPeriodType.Minute) ? BarsPeriodType.Minute : BarsPeriodType.Second, Value = 1 }; AddDataSeries(Instrument.FullName, openingRangeBarsPeriod, Instrument.MasterInstrument.TradingHours.Name); OpeningRangeBars = 1; RegularTradingHoursBars = 0; if (RegularTradingHours != Bars.TradingHours.Name) { AddDataSeries(Instrument.FullName, BarsPeriod, RegularTradingHours); RegularTradingHoursBars = 2; } } else if (State == State.DataLoaded) { SessionIterator regularTradingHoursSession = new SessionIterator(BarsArray[RegularTradingHoursBars]); RegularTradingHoursOpen = regularTradingHoursSession .GetTradingDayBeginLocal(regularTradingHoursSession.ActualTradingDayExchange).TimeOfDay; SessionIterator chartSession = new SessionIterator(BarsArray[PrimaryBars]); SessionClose = chartSession.GetTradingDayEndLocal(chartSession.ActualTradingDayExchange).TimeOfDay; } else if (State == State.Historical) { SetZOrder(-1); // Display behind bars on chart. } } protected override void OnBarUpdate() { DateTime now = Times[BarsInProgress][0]; if (Bars.IsFirstBarOfSession && IsFirstTickOfBar) { if (CurrentOpeningRange != null && now > GetSessionClose(CurrentOpeningRange.StartTime)) ResetOpeningRange(now); } if (OpeningRangeBars == BarsInProgress && now > GetOpeningRangeStartTime(now) && now <= GetOpeningRangeEndTime(now)) { if (CurrentOpeningRange == null) { CurrentOpeningRange = new OR { High = OpeningRangeHigh, Low = OpeningRangeLow, Mid = OpeningRangeMid, LatestPrice = LastPrice, StartTime = now }; OpeningRanges.Add(CurrentOpeningRange); } if (Highs[BarsInProgress][0] > OpeningRangeHigh || OpeningRangeHigh == 0.0) OpeningRangeHigh = Highs[BarsInProgress][0]; if (Lows[BarsInProgress][0] < OpeningRangeLow || OpeningRangeLow == 0.0) OpeningRangeLow = Lows[BarsInProgress][0]; } if (PrimaryBars == BarsInProgress) { ORH[0] = OpeningRangeHigh; ORL[0] = OpeningRangeLow; OpeningRangeMid = Instrument.MasterInstrument .RoundToTickSize((OpeningRangeLow + OpeningRangeHigh) / 2.0); ORM[0] = OpeningRangeMid; LastPrice = Close[0]; UpdateOpeningRange(now); } } protected override void OnRender(ChartControl chartControl, ChartScale chartScale) { base.OnRender(chartControl, chartScale); SharpDX.Direct2D1.Brush openingRangeMidBrush = OpeningRangeMidStroke.Brush.ToDxBrush(RenderTarget); TextFormat textFormat = OpeningRangeFont.ToDirectWriteTextFormat(); SharpDX.Direct2D1.Brush textBrush = OpeningRangeFontColor.ToDxBrush(RenderTarget); foreach (OR openingRange in OpeningRanges) { int barId = ChartBars.GetBarIdxByTime(chartControl, openingRange.StartTime); DateTime startTime = ChartBars.GetTimeByBarIdx(chartControl, barId); int openingRangeStartX = chartControl.GetXByTime(startTime); int openingRangeEndX; if (openingRange.EndTime == default(DateTime)) openingRangeEndX = ChartPanel.X + ChartPanel.W; else openingRangeEndX = chartControl.GetXByTime(openingRange.EndTime); if (openingRange.High > 0.0) { double openingRangeHigh = openingRange.High; float openingRangeHighEndX = openingRangeEndX; if (ShowLabels && openingRange.EndTime == default(DateTime) && openingRangeStartX < ChartPanel.X + ChartPanel.W) { SharpDX.Vector2 labelOrigin = DrawLabel(OpeningRangeHighLabel, openingRangeHigh, OpeningRangeHighLabelPosition, textFormat, textBrush, chartScale); if (OpeningRangeLabelPosition.Center == OpeningRangeHighLabelPosition) openingRangeHighEndX = labelOrigin.X - LabelPadding; } int openingRangeHighY = chartScale.GetYByValue(openingRangeHigh); if (openingRangeStartX < openingRangeHighEndX) { Stroke openingRangeHighStroke = GetStroke(openingRange, OpeningRangeHighStroke); SharpDX.Direct2D1.Brush openingRangeHighBrush = openingRangeHighStroke.Brush.ToDxBrush(RenderTarget); RenderTarget.DrawLine(new SharpDX.Vector2(openingRangeStartX, openingRangeHighY), new SharpDX.Vector2(openingRangeHighEndX, openingRangeHighY), openingRangeHighBrush, openingRangeHighStroke.Width, openingRangeHighStroke.StrokeStyle); openingRangeHighBrush.Dispose(); } } if (openingRange.Low > 0.0) { double openingRangeLow = openingRange.Low; float openingRangeLowEndX = openingRangeEndX; if (ShowLabels && openingRange.EndTime == default(DateTime) && openingRangeStartX < ChartPanel.X + ChartPanel.W) { SharpDX.Vector2 labelOrigin = DrawLabel(OpeningRangeLowLabel, openingRangeLow, OpeningRangeLowLabelPosition, textFormat, textBrush, chartScale); if (OpeningRangeLabelPosition.Center == OpeningRangeLowLabelPosition) openingRangeLowEndX = labelOrigin.X - LabelPadding; } int openingRangeLowY = chartScale.GetYByValue(openingRangeLow); if (openingRangeStartX < openingRangeLowEndX) { Stroke openingRangeLowStroke = GetStroke(openingRange, OpeningRangeLowStroke); SharpDX.Direct2D1.Brush openingRangeLowBrush = openingRangeLowStroke.Brush.ToDxBrush(RenderTarget); RenderTarget.DrawLine(new SharpDX.Vector2(openingRangeStartX, openingRangeLowY), new SharpDX.Vector2(openingRangeLowEndX, openingRangeLowY), openingRangeLowBrush, openingRangeLowStroke.Width, openingRangeLowStroke.StrokeStyle); openingRangeLowBrush.Dispose(); } } if (openingRange.Mid > 0.0) { double openingRangeMid = openingRange.Mid; float openingRangeMidEndX = openingRangeEndX; if (ShowLabels && openingRange.EndTime == default(DateTime) && openingRangeStartX < ChartPanel.X + ChartPanel.W) { SharpDX.Vector2 labelOrigin = DrawLabel(OpeningRangeMidLabel, openingRangeMid, OpeningRangeMidLabelPosition, textFormat, textBrush, chartScale); if (OpeningRangeLabelPosition.Center == OpeningRangeMidLabelPosition) openingRangeMidEndX = labelOrigin.X - LabelPadding; } int openingRangeMidY = chartScale.GetYByValue(openingRangeMid); if (openingRangeStartX < openingRangeMidEndX) RenderTarget.DrawLine(new SharpDX.Vector2(openingRangeStartX, openingRangeMidY), new SharpDX.Vector2(openingRangeMidEndX, openingRangeMidY), openingRangeMidBrush, OpeningRangeMidStroke.Width, OpeningRangeMidStroke.StrokeStyle); } if (EnableExtensions) { double range = openingRange.High - openingRange.Low; for (int i = 1; i <= NumberOfExtensions; i++) { double extension = range * ExtensionMultiplier * i; double highExtension = openingRange.High + extension; double lowExtension = openingRange.Low - extension; RenderLevel(highExtension, openingRangeStartX, openingRangeEndX, ExtensionStroke, chartScale); RenderLevel(lowExtension, openingRangeStartX, openingRangeEndX, ExtensionStroke, chartScale); } } } openingRangeMidBrush.Dispose(); textFormat.Dispose(); textBrush.Dispose(); } private void RenderLevel(double value, int startX, int endX, Stroke stroke, ChartScale scale) { SharpDX.Direct2D1.Brush brush = stroke.Brush.ToDxBrush(RenderTarget); int y = scale.GetYByValue(value); RenderTarget.DrawLine(new SharpDX.Vector2(startX, y), new SharpDX.Vector2(endX, y), brush, stroke.Width, stroke.StrokeStyle); brush.Dispose(); } private Stroke GetStroke(OR openingRange, Stroke defaultStroke) { if (ColorScheme == OpeningRangeColorScheme.PriceBased) { if (openingRange.LatestPrice > openingRange.High) return PriceAboveStroke; else if (openingRange.LatestPrice < openingRange.Low) return PriceBelowStroke; else return PriceInsideStroke; } return defaultStroke; } private SharpDX.Vector2 DrawLabel(string label, double level, OpeningRangeLabelPosition position, TextFormat textFormat, SharpDX.Direct2D1.Brush textBrush, ChartScale chartScale) { string labelText = label.Replace(LevelFormatString, level.ToString("F2")); TextLayout textLayout = new TextLayout(Core.Globals.DirectWriteFactory, labelText, textFormat, 500, textFormat.FontSize); int levelY = chartScale.GetYByValue(level); float labelY; switch (position) { case OpeningRangeLabelPosition.Below: labelY = ChartPanel.Y + (float)levelY + LabelPadding; break; case OpeningRangeLabelPosition.Center: labelY = ChartPanel.Y + (float)levelY - (textLayout.Metrics.Height / 2.0f); break; case OpeningRangeLabelPosition.Above: default: labelY = ChartPanel.Y + (float)levelY - textLayout.Metrics.Height - LabelPadding; break; } SharpDX.Vector2 textOrigin = new SharpDX.Vector2( ChartPanel.W - textLayout.Metrics.Width - LabelPadding, labelY); RenderTarget.DrawTextLayout(textOrigin, textLayout, textBrush, SharpDX.Direct2D1.DrawTextOptions.NoSnap); textLayout.Dispose(); return textOrigin; } public DateTime GetOpeningRangeStartTime(DateTime now) { return now.Date + RegularTradingHoursOpen; } public DateTime GetOpeningRangeEndTime(DateTime now) { DateTime openingRangeStartTime = GetOpeningRangeStartTime(now); switch (OpeningRangeType) { case OpeningRangeBarType.Seconds: return openingRangeStartTime.AddSeconds(OpeningRangePeriod); case OpeningRangeBarType.Hours: return openingRangeStartTime.AddHours(OpeningRangePeriod); default: return openingRangeStartTime.AddMinutes(OpeningRangePeriod); } } private DateTime GetSessionClose(DateTime openingRangeStartTime) { return openingRangeStartTime.Date + SessionClose; } private void UpdateOpeningRange(DateTime now) { if (CurrentOpeningRange != null) { CurrentOpeningRange.High = OpeningRangeHigh; CurrentOpeningRange.Low = OpeningRangeLow; CurrentOpeningRange.Mid = OpeningRangeMid; DateTime sessionClose = now.Date + SessionClose; if (GetOpeningRangeStartTime(now) > sessionClose) sessionClose = sessionClose.AddDays(1); if (CurrentOpeningRange.EndTime == default(DateTime)) { CurrentOpeningRange.LatestPrice = LastPrice; if (now >= sessionClose) CurrentOpeningRange.EndTime = sessionClose; } } } private void ResetOpeningRange(DateTime now) { OpeningRangeHigh = 0.0; OpeningRangeLow = 0.0; OpeningRangeMid = 0.0; LastPrice = 0.0; if (CurrentOpeningRange != null && CurrentOpeningRange.EndTime == default(DateTime)) CurrentOpeningRange.EndTime = now; CurrentOpeningRange = null; } public override string DisplayName { get { return Name; } } [NinjaScriptProperty] [Range(1, int.MaxValue)] [Display(Name = "Period", Description = "Opening range period", Order = 1, GroupName = "Opening Range")] public int OpeningRangePeriod { get; set; } [NinjaScriptProperty] [Display(Name = "Type", Description = "Type of opening range being calculated", Order = 2, GroupName = "Opening Range")] public OpeningRangeBarType OpeningRangeType { get; set; } [RefreshProperties(RefreshProperties.All)] [Display(Name = "Enable Extensions", Description = "Whether to enable opening range extensions", Order = 3, GroupName = "Opening Range")] public bool EnableExtensions { get; set; } [Display(Name = "Number of Extensions", Description = "Number of extensions above and below the opening range", Order = 4, GroupName = "Opening Range")] public int NumberOfExtensions { get; set; } [Display(Name = "Extension Multiplier", Description = "Multiplier used for calculating extension levels", Order = 5, GroupName = "Opening Range")] public double ExtensionMultiplier { get; set; } [PropertyEditor("NinjaTrader.Gui.Tools.StringStandardValuesEditorKey")] [TypeConverter(typeof(OpeningRangeColorSchemeConverter))] [RefreshProperties(RefreshProperties.All)] [Display(Name = "Color Scheme", Description = "Opening range coloring scheme", Order = 1, GroupName = "Appearance")] public OpeningRangeColorScheme ColorScheme { get; set; } [Display(Name = "Price Above", Description = "Opening range lines drawn on chart when price is > ORH", Order = 2, GroupName = "Appearance")] public Stroke PriceAboveStroke { get; set; } [Display(Name = "Price Below", Description = "Opening range lines drawn on chart when price is < ORL", Order = 3, GroupName = "Appearance")] public Stroke PriceBelowStroke { get; set; } [Display(Name = "Price Inside", Description = "Opening range lines drawn on chart when price is inside OR", Order = 4, GroupName = "Appearance")] public Stroke PriceInsideStroke { get; set; } [Display(Name = "Opening Range High", Description = "Opening range high line drawn on chart", Order = 5, GroupName = "Appearance")] public Stroke OpeningRangeHighStroke { get; set; } [Display(Name = "Opening Range Mid", Description = "Opening range mid line drawn on chart", Order = 6, GroupName = "Appearance")] public Stroke OpeningRangeMidStroke { get; set; } [Display(Name = "Opening Range Low", Description = "Opening range low line drawn on chart", Order = 7, GroupName = "Appearance")] public Stroke OpeningRangeLowStroke { get; set; } [Display(Name = "Extension", Description = "Opening range extensions lines drawn on chart", Order = 8, GroupName = "Appearance")] public Stroke ExtensionStroke { get; set; } [Display(Name = "Show Labels", Order = 1, GroupName = "Labels")] public bool ShowLabels { get; set; } [Display(Name = "Font", Description = "Font used to display the opening range labels", Order = 2, GroupName = "Labels")] public SimpleFont OpeningRangeFont { get; set; } [XmlIgnore] [Display(Name = "Font Color", Description = "Color of the text used to label the opening range levels", Order = 3, GroupName = "Labels")] public Brush OpeningRangeFontColor { get; set; } [Browsable(false)] public string OpeningRangeFontColorSerialization { get { return Serialize.BrushToString(OpeningRangeFontColor); } set { OpeningRangeFontColor = Serialize.StringToBrush(value); } } [Display(Name = "Opening Range High", Order = 4, GroupName = "Labels")] public string OpeningRangeHighLabel { get; set; } [Display(Name = " Label Position", Order = 5, GroupName = "Labels")] public OpeningRangeLabelPosition OpeningRangeHighLabelPosition { get; set; } [Display(Name = "Opening Range Mid", Order = 6, GroupName = "Labels")] public string OpeningRangeMidLabel { get; set; } [Display(Name = " Label Position", Order = 7, GroupName = "Labels")] public OpeningRangeLabelPosition OpeningRangeMidLabelPosition { get; set; } [Display(Name = "Opening Range Low", Order = 8, GroupName = "Labels")] public string OpeningRangeLowLabel { get; set; } [Display(Name = " Label Position", Order = 9, GroupName = "Labels")] public OpeningRangeLabelPosition OpeningRangeLowLabelPosition { get; set; } [Browsable(false)] [XmlIgnore] public Series ORH { get { return Values[0]; } } [Browsable(false)] [XmlIgnore] public Series ORL { get { return Values[1]; } } [Browsable(false)] [XmlIgnore] public Series ORM { get { return Values[2]; } } } public class OpeningRangePropertyConverter : IndicatorBaseConverter { public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object component, Attribute[] attrs) { OpeningRange indicator = component as OpeningRange; PropertyDescriptorCollection properties = base.GetPropertiesSupported(context) ? base.GetProperties(context, component, attrs) : TypeDescriptor.GetProperties(component, attrs); if (indicator == null || properties == null) return properties; PropertyDescriptor numberOfExtensions = properties["NumberOfExtensions"]; PropertyDescriptor extensionMultiplier = properties["ExtensionMultiplier"]; PropertyDescriptor extensionStroke = properties["ExtensionStroke"]; properties.Remove(numberOfExtensions); properties.Remove(extensionMultiplier); properties.Remove(extensionStroke); if (indicator.EnableExtensions) { properties.Add(numberOfExtensions); properties.Add(extensionMultiplier); properties.Add(extensionStroke); } PropertyDescriptor priceAboveStroke = properties["PriceAboveStroke"]; PropertyDescriptor priceBelowStroke = properties["PriceBelowStroke"]; PropertyDescriptor priceInsideStroke = properties["PriceInsideStroke"]; properties.Remove(priceAboveStroke); properties.Remove(priceBelowStroke); properties.Remove(priceInsideStroke); if (indicator.ColorScheme == OpeningRangeColorScheme.PriceBased) { PropertyDescriptor openingRangeHighStroke = properties["OpeningRangeHighStroke"]; PropertyDescriptor openingRangeLowStroke = properties["OpeningRangeLowStroke"]; properties.Remove(openingRangeHighStroke); properties.Remove(openingRangeLowStroke); properties.Add(priceAboveStroke); properties.Add(priceBelowStroke); properties.Add(priceInsideStroke); } return properties; } public override bool GetPropertiesSupported(ITypeDescriptorContext context) { return true; } } } public class OpeningRangeColorSchemeConverter : TypeConverter { private const string DEFAULT = "Default"; private const string PRICE_BASED = "Price Based"; public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { List values = new List() { DEFAULT, PRICE_BASED }; return new StandardValuesCollection(values); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { switch (value.ToString()) { case DEFAULT: return OpeningRangeColorScheme.Default; case PRICE_BASED: return OpeningRangeColorScheme.PriceBased; } return OpeningRangeColorScheme.Default; } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { OpeningRangeColorScheme enumValue = (OpeningRangeColorScheme)Enum.Parse(typeof(OpeningRangeColorScheme), value.ToString()); switch (enumValue) { case OpeningRangeColorScheme.Default: return DEFAULT; case OpeningRangeColorScheme.PriceBased: return PRICE_BASED; } return DEFAULT; } public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return true; } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return true; } public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) { return true; } public override bool GetStandardValuesSupported(ITypeDescriptorContext context) { return true; } } public enum OpeningRangeBarType { Seconds, Minutes, Hours } public enum OpeningRangeColorScheme { Default, PriceBased } public enum OpeningRangeLabelPosition { Above, Below, Center } #region NinjaScript generated code. Neither change nor remove. namespace NinjaTrader.NinjaScript.Indicators { public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase { private OpeningRange[] cacheOpeningRange; public OpeningRange OpeningRange(int openingRangePeriod, OpeningRangeBarType openingRangeType) { return OpeningRange(Input, openingRangePeriod, openingRangeType); } public OpeningRange OpeningRange(ISeries input, int openingRangePeriod, OpeningRangeBarType openingRangeType) { 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].EqualsInput(input)) return cacheOpeningRange[idx]; return CacheIndicator(new OpeningRange(){ OpeningRangePeriod = openingRangePeriod, OpeningRangeType = openingRangeType }, input, ref cacheOpeningRange); } } } namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns { public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase { public Indicators.OpeningRange OpeningRange(int openingRangePeriod, OpeningRangeBarType openingRangeType) { return indicator.OpeningRange(Input, openingRangePeriod, openingRangeType); } public Indicators.OpeningRange OpeningRange(ISeries input , int openingRangePeriod, OpeningRangeBarType openingRangeType) { return indicator.OpeningRange(input, openingRangePeriod, openingRangeType); } } } namespace NinjaTrader.NinjaScript.Strategies { public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase { public Indicators.OpeningRange OpeningRange(int openingRangePeriod, OpeningRangeBarType openingRangeType) { return indicator.OpeningRange(Input, openingRangePeriod, openingRangeType); } public Indicators.OpeningRange OpeningRange(ISeries input , int openingRangePeriod, OpeningRangeBarType openingRangeType) { return indicator.OpeningRange(input, openingRangePeriod, openingRangeType); } } } #endregion