#region Using declarations using NinjaTrader.Gui; using NinjaTrader.Gui.Chart; 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 //This namespace holds Indicators in this folder and is required. Do not change it. namespace NinjaTrader.NinjaScript.Indicators { [CategoryOrder("VIX Ratio", 1)] [CategoryOrder("Plots", 2)] public class VIXRatio : Indicator { private const int NumeratorBars = 1; private const int DenominatorBars = 2; private EMA fastEMA; private EMA slowEMA; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Only works with a data feed that provides the relevant VIX indices"; Name = "VIX Ratio"; Calculate = Calculate.OnBarClose; BarsRequiredToPlot = 1; IsOverlay = false; DisplayInDataBox = true; DrawOnPricePanel = true; PaintPriceMarkers = false; ScaleJustification = ScaleJustification.Right; Numerator = VIXIndex.VIX; Denominator = VIXIndex.VIX3M; FastEMAPeriod = 7; SlowEMAPeriod = 12; AddPlot(new Stroke(Brushes.Yellow, 3), PlotStyle.Line, "VIX Ratio"); AddPlot(new Stroke(Brushes.Green, 3), PlotStyle.Line, "Fast EMA"); AddPlot(new Stroke(Brushes.Red, 3), PlotStyle.Line, "Slow EMA"); } else if (State == State.Configure) { AddDataSeries(Numerator.ToSymbol()); AddDataSeries(Denominator.ToSymbol()); } else if (State == State.DataLoaded) { fastEMA = EMA(Ratio, FastEMAPeriod); slowEMA = EMA(Ratio, SlowEMAPeriod); } } protected override void OnBarUpdate() { if (CurrentBars[NumeratorBars] < 1 || CurrentBars[DenominatorBars] < 1) return; // Denominator bars should be processed last according to NT documentation on bar processing order. if (BarsInProgress == DenominatorBars) { Ratio[0] = Closes[NumeratorBars][0] / Closes[DenominatorBars][0]; if (CurrentBar >= Math.Max(FastEMAPeriod, SlowEMAPeriod)) { FastEMA[0] = fastEMA[0]; SlowEMA[0] = slowEMA[0]; } } } public override string DisplayName { get { return Numerator.ToString() + " / " + Denominator.ToString(); } } [NinjaScriptProperty] [PropertyEditor("NinjaTrader.Gui.Tools.StringStandardValuesEditorKey")] [TypeConverter(typeof(VIXIndexConverter))] [Display(Name = "Numerator", Order = 1, GroupName = "VIX Ratio")] public VIXIndex Numerator { get; set; } [NinjaScriptProperty] [PropertyEditor("NinjaTrader.Gui.Tools.StringStandardValuesEditorKey")] [TypeConverter(typeof(VIXIndexConverter))] [Display(Name = "Denominator", Order = 2, GroupName = "VIX Ratio")] public VIXIndex Denominator { get; set; } [NinjaScriptProperty] [Range(1, int.MaxValue)] [Display(Name = "Fast EMA Period", Order = 3, GroupName = "VIX Ratio")] public int FastEMAPeriod { get; set; } [NinjaScriptProperty] [Range(1, int.MaxValue)] [Display(Name = "Slow EMA Period", Order = 4, GroupName = "VIX Ratio")] public int SlowEMAPeriod { get; set; } [Browsable(false)] [XmlIgnore] public Series Ratio { get { return Values[0]; } } [Browsable(false)] [XmlIgnore] public Series FastEMA { get { return Values[1]; } } [Browsable(false)] [XmlIgnore] public Series SlowEMA { get { return Values[2]; } } } } public enum VIXIndex { VIX1D, VIX9D, VIX, VIX3M, VIX6M, VIX1Y } public static class VIXIndexExtensions { public static string ToSymbol(this VIXIndex value) { switch (value) { case VIXIndex.VIX1D: return "^VIX1D"; case VIXIndex.VIX9D: return "^VIX9D"; case VIXIndex.VIX3M: return "^VIX3M"; case VIXIndex.VIX6M: return "^VIX6M"; case VIXIndex.VIX1Y: return "^VIX1Y"; default: return "^VIX"; } } } public class VIXIndexConverter : TypeConverter { private const string VIX1D = "VIX1D"; private const string VIX9D = "VIX9D"; private const string VIX = "VIX"; private const string VIX3M = "VIX3M"; private const string VIX6M = "VIX6M"; private const string VIX1Y = "VIX1Y"; public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { return new StandardValuesCollection(new List { VIX1D, VIX9D, VIX, VIX3M, VIX6M, VIX1Y }); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { switch (value.ToString()) { case VIX1D: return VIXIndex.VIX1D; case VIX9D: return VIXIndex.VIX9D; case VIX3M: return VIXIndex.VIX3M; case VIX6M: return VIXIndex.VIX6M; case VIX1Y: return VIXIndex.VIX1Y; default: return VIXIndex.VIX; } } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { VIXIndex enumValue = (VIXIndex)Enum.Parse(typeof(VIXIndex), value.ToString()); switch (enumValue) { case VIXIndex.VIX1D: return VIX1D; case VIXIndex.VIX9D: return VIX9D; case VIXIndex.VIX3M: return VIX3M; case VIXIndex.VIX6M: return VIX6M; case VIXIndex.VIX1Y: return VIX1Y; default: return VIX; } } 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; } } #region NinjaScript generated code. Neither change nor remove. namespace NinjaTrader.NinjaScript.Indicators { public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase { private VIXRatio[] cacheVIXRatio; public VIXRatio VIXRatio(VIXIndex numerator, VIXIndex denominator, int fastEMAPeriod, int slowEMAPeriod) { return VIXRatio(Input, numerator, denominator, fastEMAPeriod, slowEMAPeriod); } public VIXRatio VIXRatio(ISeries input, VIXIndex numerator, VIXIndex denominator, int fastEMAPeriod, int slowEMAPeriod) { if (cacheVIXRatio != null) for (int idx = 0; idx < cacheVIXRatio.Length; idx++) if (cacheVIXRatio[idx] != null && cacheVIXRatio[idx].Numerator == numerator && cacheVIXRatio[idx].Denominator == denominator && cacheVIXRatio[idx].FastEMAPeriod == fastEMAPeriod && cacheVIXRatio[idx].SlowEMAPeriod == slowEMAPeriod && cacheVIXRatio[idx].EqualsInput(input)) return cacheVIXRatio[idx]; return CacheIndicator(new VIXRatio(){ Numerator = numerator, Denominator = denominator, FastEMAPeriod = fastEMAPeriod, SlowEMAPeriod = slowEMAPeriod }, input, ref cacheVIXRatio); } } } namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns { public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase { public Indicators.VIXRatio VIXRatio(VIXIndex numerator, VIXIndex denominator, int fastEMAPeriod, int slowEMAPeriod) { return indicator.VIXRatio(Input, numerator, denominator, fastEMAPeriod, slowEMAPeriod); } public Indicators.VIXRatio VIXRatio(ISeries input , VIXIndex numerator, VIXIndex denominator, int fastEMAPeriod, int slowEMAPeriod) { return indicator.VIXRatio(input, numerator, denominator, fastEMAPeriod, slowEMAPeriod); } } } namespace NinjaTrader.NinjaScript.Strategies { public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase { public Indicators.VIXRatio VIXRatio(VIXIndex numerator, VIXIndex denominator, int fastEMAPeriod, int slowEMAPeriod) { return indicator.VIXRatio(Input, numerator, denominator, fastEMAPeriod, slowEMAPeriod); } public Indicators.VIXRatio VIXRatio(ISeries input , VIXIndex numerator, VIXIndex denominator, int fastEMAPeriod, int slowEMAPeriod) { return indicator.VIXRatio(input, numerator, denominator, fastEMAPeriod, slowEMAPeriod); } } } #endregion