#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 namespace NinjaTrader.NinjaScript.Indicators { /// /// The Daily Factor Indicator was created by Andrea Unger (Stocks and Commodities Jun 2023 pgs 26-31), and this is a new volatility indicator /// that compares the body, which is the absolute difference between the previous open and previous close, and the range which is the difference /// between the previous high and previous low. The indicator is calculated by dividing the body and range to determine the volatility for the /// previous bar. This indicator will range between 0 and 1. Values closer to 1 mean very high volatility, and values closer to 0 mean very low /// volatility. /// public class DFI : Indicator { private Stroke hLine; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Daily Factor Indicator v1.2 by @fercho"; Name = "DFI"; Calculate = Calculate.OnBarClose; IsOverlay = false; DrawOnPricePanel = false; IsSuspendedWhileInactive = true; ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right; DFLevel = 0.70; AddPlot(Brushes.Red, "Daily Factor"); hLine = new Stroke(Brushes.DarkCyan, DashStyleHelper.DashDot, 1); AddLine(hLine,DFLevel,"DFLevel"); } if (State == State.Configure) { } } protected override void OnBarUpdate() { if (CurrentBar < 2) return; // Calculate Daily Factor DF[0] = High[0] != Low[0] ? Math.Abs(Open[0] - Close[0])/(High[0] - Low[0]) : 0; } #region Properties​ [Browsable(false)] [XmlIgnore()] public Series DF { get { return Values[0]; } } [NinjaScriptProperty] [Range(0, 1)] [Display(Name = "Daily Factor Threshold Level", Order = 0, GroupName = "Parameters")] public double DFLevel { get; set; } #endregion } } #region NinjaScript generated code. Neither change nor remove. namespace NinjaTrader.NinjaScript.Indicators { public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase { private DFI[] cacheDFI; public DFI DFI(double dFLevel) { return DFI(Input, dFLevel); } public DFI DFI(ISeries input, double dFLevel) { if (cacheDFI != null) for (int idx = 0; idx < cacheDFI.Length; idx++) if (cacheDFI[idx] != null && cacheDFI[idx].DFLevel == dFLevel && cacheDFI[idx].EqualsInput(input)) return cacheDFI[idx]; return CacheIndicator(new DFI(){ DFLevel = dFLevel }, input, ref cacheDFI); } } } namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns { public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase { public Indicators.DFI DFI(double dFLevel) { return indicator.DFI(Input, dFLevel); } public Indicators.DFI DFI(ISeries input , double dFLevel) { return indicator.DFI(input, dFLevel); } } } namespace NinjaTrader.NinjaScript.Strategies { public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase { public Indicators.DFI DFI(double dFLevel) { return indicator.DFI(Input, dFLevel); } public Indicators.DFI DFI(ISeries input , double dFLevel) { return indicator.DFI(input, dFLevel); } } } #endregion