[HandlerName("NRMA(-NRTR)")] [HandlerCategory("vvAverages")] public class NRMA : IBar2DoubleHandler, IContextUses { [HandlerParameter(true, "2", Min = "2", Max = "20", Step = "1")] public int Fast { get; set; } // минимальный период средней [HandlerParameter(true, "0.5", Min = "0.1", Max = "10", Step = "0.1")] public double Offset { get; set; } // коэффициент смещения (%) - в оригинале - K [HandlerParameter(true, "2", Min = "2", Max = "3", Step = "1")] public int Sharp { get; set; } // Sharp - степень для усиления выраженности индикатора (2-3) [HandlerParameter(true, "3", Min = "2", Max = "10", Step = "1")] public int Smooth { get; set; } // [HandlerParameter(false, "false", NotOptimized = true)] public bool ShowNRTR { get; set; } public IList GenNRMA(ISecurity source, double _K, int _Sharp, int _Fast, int _Smooth) { int count = source.Bars.Count; var Cl = source.ClosePrices; var Op = source.OpenPrices; double[] Trend = new double[count]; double[] LPrice = new double[count]; double[] HPrice = new double[count]; double[] NRTR = new double[count]; double[] NRMA = new double[count]; double[] Oscil = new double[count]; double[] NRatio = new double[count]; double F = 2 / (1.0 + Fast); //было F=1/(2.0+Fast); //---- подготовка нулевых баров в массивах if (source.ClosePrices[0] > source.OpenPrices[0]) { Trend[0] = 1.0; LPrice[0] = Cl[0] * (1.0 - _K * 0.01); HPrice[0] = 0.0; NRTR[0] = LPrice[0]; } else { Trend[0] = -1.0; HPrice[0] = Cl[0] * (1.0 + _K * 0.01); LPrice[0] = 0.0; NRTR[0] = HPrice[0]; } for (int i = 0; i < 100; i++) NRMA[i] = Cl[i]; //---- for (int i = 1; i < count; i++) { if (Trend[i - 1] > 0) //---- тренд вверх { if (Cl[i] < NRTR[i - 1]) { Trend[i] = -1.0; HPrice[i] = Cl[i] * (1.0 + _K * 0.01); LPrice[i] = 0.0; NRTR[i] = HPrice[i]; } else { Trend[i] = 1.0; LPrice[i] = Cl[i] * (1.0 - _K * 0.01); HPrice[i] = 0.0; if (LPrice[i] > NRTR[i - 1]) NRTR[i] = LPrice[i]; else NRTR[i] = NRTR[i - 1]; } } else //---- тренд вниз { if (Cl[i] > NRTR[i - 1]) { Trend[i] = 1.0; LPrice[i] = Cl[i] * (1.0 - _K * 0.01); HPrice[i] = 0.0; NRTR[i] = LPrice[i]; } else { Trend[i] = -1.0; HPrice[i] = Cl[i] * (1.0 + _K * 0.01); LPrice[i] = 0.0; if (HPrice[i] < NRTR[i - 1]) NRTR[i] = HPrice[i]; else NRTR[i] = NRTR[i - 1]; } } Oscil[i] = (100.0 * Math.Abs(Cl[i] - NRTR[i]) / Cl[i]) / _K; } //---- Oscil[0] = Oscil[1]; var buf = Series.SMA(Oscil, _Smooth); for (int i = 1; i < count; i++) { NRatio[i] = Math.Pow(Oscil[i], Sharp); NRMA[i] = NRMA[i - 1] + NRatio[i] * F * (Cl[i] - NRMA[i - 1]); } return ShowNRTR ? NRTR : NRMA; } public IList Execute(ISecurity source) { return GenNRMA(source, Offset, Sharp, Fast, Smooth); } public IContext Context { get; set; } }