#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 SilverBullet : Indicator { private const string RegularTradingHours = "US Equities RTH"; private int RegularTradingHoursBars; private DateTime RangeStartTime; private DateTime RangeEndTime; private DateTime LastTradingDay; private class DailyRange { public DateTime Date { get; set; } public double High { get; set; } public double Low { get; set; } } private List DailyRanges = new List(); private DailyRange CurrentDailyRange; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @""; Name = "Silver Bullet"; Calculate = Calculate.OnPriceChange; IsOverlay = true; DisplayInDataBox = true; DrawOnPricePanel = true; DrawHorizontalGridLines = true; DrawVerticalGridLines = true; PaintPriceMarkers = true; ScaleJustification = ScaleJustification.Right; IsSuspendedWhileInactive = true; } else if (State == State.Configure) { RegularTradingHoursBars = 0; if (RegularTradingHours != Bars.TradingHours.Name) { // TODO: Use whatever data series is currently on the chart. AddDataSeries(Instrument.FullName, new BarsPeriod { BarsPeriodType = BarsPeriodType.Minute, Value = 60 }, RegularTradingHours); RegularTradingHoursBars = 1; } } else if (State == State.DataLoaded) { SessionIterator regularTradingHoursSession = new SessionIterator(BarsArray[RegularTradingHoursBars]); DateTime regularTradingHoursOpen = regularTradingHoursSession.GetTradingDayBeginLocal(regularTradingHoursSession.ActualTradingDayExchange); RangeStartTime = regularTradingHoursOpen.AddMinutes(-30); // 09:00 AM ET RangeEndTime = regularTradingHoursOpen.AddMinutes(30); // 10:00 AM ET } else if (State == State.Historical) { SetZOrder(-1); // Display behind bars on chart. } } protected override void OnBarUpdate() { if (BarsInProgress != 0) return; DateTime now = Times[BarsInProgress][0]; if (now.Date != LastTradingDay) { LastTradingDay = now.Date; CurrentDailyRange = new DailyRange { Date = LastTradingDay, High = double.MinValue, Low = double.MinValue }; DailyRanges.Add(CurrentDailyRange); } if (now > (now.Date + RangeStartTime.TimeOfDay) && now <= (now.Date + RangeEndTime.TimeOfDay)) { if (Highs[BarsInProgress][0] > CurrentDailyRange.High || CurrentDailyRange.High == double.MinValue) CurrentDailyRange.High = Highs[BarsInProgress][0]; if (Lows[BarsInProgress][0] < CurrentDailyRange.Low || CurrentDailyRange.Low == double.MinValue) CurrentDailyRange.Low = Lows[BarsInProgress][0]; } } protected override void OnRender(ChartControl chartControl, ChartScale chartScale) { base.OnRender(chartControl, chartScale); foreach (var dailyRange in DailyRanges) { if (dailyRange.High == double.MinValue || dailyRange.Low == double.MinValue) continue; int startX = chartControl.GetXByTime(dailyRange.Date + RangeStartTime.TimeOfDay); int endX = chartControl.GetXByTime(dailyRange.Date + RangeEndTime.AddHours(1).TimeOfDay); int highY = chartScale.GetYByValue(dailyRange.High); RenderTarget.DrawLine(new SharpDX.Vector2(startX, highY), new SharpDX.Vector2(endX, highY), Brushes.LimeGreen.ToDxBrush(RenderTarget), 3); int lowY = chartScale.GetYByValue(dailyRange.Low); RenderTarget.DrawLine(new SharpDX.Vector2(startX, lowY), new SharpDX.Vector2(endX, lowY), Brushes.Red.ToDxBrush(RenderTarget), 3); } } public override string DisplayName { get { return Name; } } } } #region NinjaScript generated code. Neither change nor remove. namespace NinjaTrader.NinjaScript.Indicators { public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase { private SilverBullet[] cacheSilverBullet; public SilverBullet SilverBullet() { return SilverBullet(Input); } public SilverBullet SilverBullet(ISeries input) { if (cacheSilverBullet != null) for (int idx = 0; idx < cacheSilverBullet.Length; idx++) if (cacheSilverBullet[idx] != null && cacheSilverBullet[idx].EqualsInput(input)) return cacheSilverBullet[idx]; return CacheIndicator(new SilverBullet(), input, ref cacheSilverBullet); } } } namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns { public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase { public Indicators.SilverBullet SilverBullet() { return indicator.SilverBullet(Input); } public Indicators.SilverBullet SilverBullet(ISeries input ) { return indicator.SilverBullet(input); } } } namespace NinjaTrader.NinjaScript.Strategies { public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase { public Indicators.SilverBullet SilverBullet() { return indicator.SilverBullet(Input); } public Indicators.SilverBullet SilverBullet(ISeries input ) { return indicator.SilverBullet(input); } } } #endregion