using System; using System.ComponentModel; using System.Drawing; using System.Xml.Serialization; using NinjaTrader.Data; using NinjaTrader.Gui.Chart; //+------------------------------------------------------------------+ //| StepMA_v7.2.mq4 | //| Copyright © 2006, TrendLaboratory | //| http://finance.groups.yahoo.com/group/TrendLaboratory | //| E-mail: igorad2003@yahoo.co.uk | //+------------------------------------------------------------------+ //| Modifications: | //| - StepMA_v7.2, 2006/06/26, by Ogeima, ph_bresson@yahoo.com | //| - Color Mode 3 | //| - UpDownShift to ColorMode2 and ColorMode3 | //| - Fixed LineBuffer[] for every ColorMode, in order to enable | //| applying a MovingAverage(1) on top of the StepMA, | //| thus enabling the charting of LevelLines on the StepMA | //+------------------------------------------------------------------+ namespace NinjaTrader.Indicator { /// /// StepMA v7.2, ported from MT code by Igorad /// [Description("")] public class StepMA : Indicator { //Inputs private int _length = 10; // Volty Length private double _kv = 0.5; // Sensivity Factor private int _stepSize = 20; // Constant Step Size (if need) private int _maType; // Volty MA Mode : 0-SMA, 1-LWMA private double _percentage; // Percentage of Up/Down Moving private double _upDownShift; // Number of Up/Down Moving, in points. For ColorMode==3 only. private bool _highLow; // High/Low Mode Switch (more sensitive) private int _colorMode = 2; // Color Mode Switch private double stepMA, ATR0, ATRmax = -100000, ATRmin = 1000000; private int limit; private DataSeries smin; private DataSeries smax; private DataSeries trend; /// /// This method is used to configure the indicator and is called once before any bar data is loaded. /// protected override void Initialize() { Add(new Plot(Color.FromKnownColor(KnownColor.Yellow), PlotStyle.Line, "StepNeutral")); Add(new Plot(Color.FromKnownColor(KnownColor.Cyan), PlotStyle.Line, "StepUp")); Add(new Plot(Color.FromKnownColor(KnownColor.Magenta), PlotStyle.Line, "StepDn")); Plots[0].Pen.Width = 2; Plots[1].Pen.Width = 2; Plots[2].Pen.Width = 2; smin = new DataSeries(this); smax = new DataSeries(this); trend = new DataSeries(this); CalculateOnBarClose = false; Overlay = true; PriceTypeSupported = false; } /// /// Called on each bar update event (incoming tick) /// protected override void OnBarUpdate() { if (CurrentBar <= Length) return; double step = StepSizeCalc(Length, Kv, StepSize, 0); stepMA = StepMACalc(HighLow, step)+Percentage/100.0*step*TickSize; if (ColorMode == 0) LineBuffer[0] = stepMA; if (ColorMode == 1) { if (trend[0] > 0) { UpBuffer[0] = stepMA-step*TickSize; } else if (trend[0] < 0) { DnBuffer[0] = stepMA+step*TickSize; } } else if (ColorMode == 2) { if (trend[0] > 0) { UpBuffer[0] = stepMA+UpDownShift*TickSize; if (trend[1] < 0) UpBuffer[1] = DnBuffer[1]; } if (trend[0] < 0) { DnBuffer[0] = stepMA-UpDownShift*TickSize; if (trend[1] > 0) DnBuffer[1] = UpBuffer[1]; } } //end if ( ColorMode == 2) else if (ColorMode == 3) { if (trend[0] > 0) { UpBuffer[0] = stepMA+(step+UpDownShift)*TickSize; } else if (trend[0] < 0) { DnBuffer[0] = stepMA-(step+UpDownShift)*TickSize; } } //end if ( ColorMode == 3) else { LineBuffer[0] = stepMA; } } private double StepSizeCalc(int Len, double Km, int Size, int k) { double result; if (Size == 0) { double AvgRange = 0; double Weight = 0; for (int i = Len-1; i >= 0; i--) { double alfa = (MaType == 0) ? 1.0 : 1.0*(Len-i)/Len; AvgRange += alfa*(High[k+i]-Low[k+i]); Weight += alfa; } ATR0 = AvgRange/Weight; if (ATR0 > ATRmax) ATRmax = ATR0; if (ATR0 < ATRmin) ATRmin = ATR0; result = Math.Round(0.5*Km*(ATRmax+ATRmin)/TickSize); } else result = Km*StepSize; return result; } private double StepMACalc(bool HL, double Size) { double result; if (HL) { smax[0] = Low[0]+2.0*Size*TickSize; smin[0] = High[0]-2.0*Size*TickSize; } else { smax[0] = Close[0]+2.0*Size*TickSize; smin[0] = Close[0]-2.0*Size*TickSize; } if (CurrentBar == Length) { smax[1] = smax[0]; smin[1] = smin[0]; trend[1] = 0; } trend[0] = trend[1]; if (Close[0] > smax[1]) trend[0] = 1; if (Close[0] < smin[1]) trend[0] = -1; if (trend[0] > 0) { if (smin[0] < smin[1]) smin[0] = smin[1]; result = smin[0]+Size*TickSize; } else { if (smax[0] > smax[1]) smax[0] = smax[1]; result = smax[0]-Size*TickSize; } return (result); } #region Properties [Browsable(false)] [XmlIgnore] public DataSeries UpBuffer { get { return Values[1]; } } [Browsable(false)] [XmlIgnore] public DataSeries DnBuffer { get { return Values[2]; } } [Browsable(false)] [XmlIgnore] public DataSeries LineBuffer { get { return Values[0]; } } [Description("")] [Category("Parameters")] public int Length { get { return _length; } set { _length = value; } } [Description("")] [Category("Parameters")] public double Kv { get { return _kv; } set { _kv = value; } } [Description("")] [Category("Parameters")] public int StepSize { get { return _stepSize; } set { _stepSize = value; } } [Description("")] [Category("Parameters")] public int MaType { get { return _maType; } set { _maType = value; } } [Description("")] [Category("Parameters")] public double Percentage { get { return _percentage; } set { _percentage = value; } } [Description("")] [Category("Parameters")] public double UpDownShift { get { return _upDownShift; } set { _upDownShift = value; } } [Description("")] [Category("Parameters")] public bool HighLow { get { return _highLow; } set { _highLow = value; } } [Description("")] [Category("Parameters")] public int ColorMode { get { return _colorMode; } set { _colorMode = value; } } #endregion } } #region NinjaScript generated code. Neither change nor remove. // This namespace holds all indicators and is required. Do not change it. namespace NinjaTrader.Indicator { public partial class Indicator : IndicatorBase { private StepMA[] cacheStepMA = null; private static StepMA checkStepMA = new StepMA(); /// /// /// /// public StepMA StepMA(int colorMode, bool highLow, double kv, int length, int maType, double percentage, int stepSize, double upDownShift) { return StepMA(Input, colorMode, highLow, kv, length, maType, percentage, stepSize, upDownShift); } /// /// /// /// public StepMA StepMA(Data.IDataSeries input, int colorMode, bool highLow, double kv, int length, int maType, double percentage, int stepSize, double upDownShift) { checkStepMA.ColorMode = colorMode; colorMode = checkStepMA.ColorMode; checkStepMA.HighLow = highLow; highLow = checkStepMA.HighLow; checkStepMA.Kv = kv; kv = checkStepMA.Kv; checkStepMA.Length = length; length = checkStepMA.Length; checkStepMA.MaType = maType; maType = checkStepMA.MaType; checkStepMA.Percentage = percentage; percentage = checkStepMA.Percentage; checkStepMA.StepSize = stepSize; stepSize = checkStepMA.StepSize; checkStepMA.UpDownShift = upDownShift; upDownShift = checkStepMA.UpDownShift; if (cacheStepMA != null) for (int idx = 0; idx < cacheStepMA.Length; idx++) if (cacheStepMA[idx].ColorMode == colorMode && cacheStepMA[idx].HighLow == highLow && Math.Abs(cacheStepMA[idx].Kv - kv) <= double.Epsilon && cacheStepMA[idx].Length == length && cacheStepMA[idx].MaType == maType && Math.Abs(cacheStepMA[idx].Percentage - percentage) <= double.Epsilon && cacheStepMA[idx].StepSize == stepSize && Math.Abs(cacheStepMA[idx].UpDownShift - upDownShift) <= double.Epsilon && cacheStepMA[idx].EqualsInput(input)) return cacheStepMA[idx]; StepMA indicator = new StepMA(); indicator.BarsRequired = BarsRequired; indicator.CalculateOnBarClose = CalculateOnBarClose; indicator.Input = input; indicator.ColorMode = colorMode; indicator.HighLow = highLow; indicator.Kv = kv; indicator.Length = length; indicator.MaType = maType; indicator.Percentage = percentage; indicator.StepSize = stepSize; indicator.UpDownShift = upDownShift; indicator.SetUp(); StepMA[] tmp = new StepMA[cacheStepMA == null ? 1 : cacheStepMA.Length + 1]; if (cacheStepMA != null) cacheStepMA.CopyTo(tmp, 0); tmp[tmp.Length - 1] = indicator; cacheStepMA = tmp; Indicators.Add(indicator); return indicator; } } } // This namespace holds all market analyzer column definitions and is required. Do not change it. namespace NinjaTrader.MarketAnalyzer { public partial class Column : ColumnBase { /// /// /// /// [Gui.Design.WizardCondition("Indicator")] public Indicator.StepMA StepMA(int colorMode, bool highLow, double kv, int length, int maType, double percentage, int stepSize, double upDownShift) { return _indicator.StepMA(Input, colorMode, highLow, kv, length, maType, percentage, stepSize, upDownShift); } /// /// /// /// public Indicator.StepMA StepMA(Data.IDataSeries input, int colorMode, bool highLow, double kv, int length, int maType, double percentage, int stepSize, double upDownShift) { return _indicator.StepMA(input, colorMode, highLow, kv, length, maType, percentage, stepSize, upDownShift); } } } // This namespace holds all strategies and is required. Do not change it. namespace NinjaTrader.Strategy { public partial class Strategy : StrategyBase { /// /// /// /// [Gui.Design.WizardCondition("Indicator")] public Indicator.StepMA StepMA(int colorMode, bool highLow, double kv, int length, int maType, double percentage, int stepSize, double upDownShift) { return _indicator.StepMA(Input, colorMode, highLow, kv, length, maType, percentage, stepSize, upDownShift); } /// /// /// /// public Indicator.StepMA StepMA(Data.IDataSeries input, int colorMode, bool highLow, double kv, int length, int maType, double percentage, int stepSize, double upDownShift) { if (InInitialize && input == null) throw new ArgumentException("You only can access an indicator with the default input/bar series from within the 'Initialize()' method"); return _indicator.StepMA(input, colorMode, highLow, kv, length, maType, percentage, stepSize, upDownShift); } } } #endregion