[HandlerName("StepRSI2")] [HandlerCategory("vvRSI")] public class StepRSI2 : IDouble2DoubleHandler, IContextUses { // old version [HandlerParameter(true, "14", Min = "5", Max = "30", Step = "1")] public int RSIperiod { get; set; } // [HandlerParameter(true, "5", Min = "1", Max = "20", Step = "1")] public int StepSize { get; set; } // [HandlerParameter(true, "1", Min = "1", Max = "20", Step = "1")] public int Smooth { get; set; } // [HandlerParameter(false, "false", NotOptimized = true)] public bool Chart { get; set; } [HandlerParameter(false, "false", NotOptimized = true)] public bool GetSignals { get; set; } [HandlerParameter(false, "false", NotOptimized = true)] public bool Mode1 { get; set; } [HandlerParameter(false, "false", NotOptimized = true)] public bool StepRSIfast { get; set; } public static IList GenStepRSI2(IList src, IContext Ctx, int _RSIperiod, int _StepSize, int _Smooth, bool _Chart, bool _GetSignals, bool _Mode1, bool _StepRSIfast) { #region variables var bars = src.Count; double rel, negative, positive; int cyclestart = _RSIperiod; IList RSIBuffer = Ctx.GetData("r", new[] { _RSIperiod.ToString() }, () => RSI.RSI_TSLab(src, _RSIperiod)); //IList RSIBuffer = r; var SlowBuffer = new double[bars]; //var RSIBuffer = new double[bars]; var TradeSigBuf = new double[bars]; var smax = new double[bars]; var smin = new double[bars]; var trend = new double[bars]; //for (int i = 0; i < src.Count; i++) RSIBuffer[i] = r[i]; //---- здесь используется MAperiod для сглаживания входящих цен //var ma = Ctx.GetData("ma", new[] { _MAperiod.ToString() }, () => SMA.GenSMA(src, _MAperiod)); #endregion #region основной цикл for (int i = cyclestart; i < src.Count; i++) { //---- накопление данных в RSIperiod double sumn = 0.0, sump = 0.0; for (int k = 0; k < _RSIperiod; k++) { rel = src[i - k] - src[i - k - 1]; if (rel > 0) sump += rel; else sumn -= rel; } positive = sump / _RSIperiod; negative = sumn / _RSIperiod; //---- если Mode1 if (_Mode1) { if (negative == 0.0) RSIBuffer[i] = 100.0; else RSIBuffer[i] = 100.0 - 100.0 / (1.0 + positive / negative); } //---- StepMA_5.2 double result = 0; smax[i] = RSIBuffer[i] + 2.0 * _StepSize; smin[i] = RSIBuffer[i] - 2.0 * _StepSize; trend[i] = trend[i - 1]; if (trend[i - 1] <= 0 && RSIBuffer[i] > smax[i - 1]) trend[i] = 1; if (trend[i - 1] >= 0 && RSIBuffer[i] < smin[i - 1]) trend[i] = -1; if (trend[i] > 0) { if (smin[i] < smin[i - 1]) smin[i] = smin[i - 1]; result = smin[i] + _StepSize; } else if (trend[i] < 0) { if (smax[i] > smax[i - 1]) smax[i] = smax[i - 1]; result = smax[i] - _StepSize; } SlowBuffer[i] = result; } //---- smoothing by JMA var rsi = JMA.GenJMA(RSIBuffer, _Smooth, 100); //---- торговые сигналы if (_GetSignals) { for (int k = 1; k < src.Count; k++) { TradeSigBuf[0] = 0; if (rsi[k] > SlowBuffer[k] && rsi[k - 1] < SlowBuffer[k - 1]) TradeSigBuf[k] = 1; if (rsi[k] < SlowBuffer[k] && rsi[k - 1] > SlowBuffer[k - 1]) TradeSigBuf[k] = -1; } } #endregion #region вывод графика if (_Chart) { var Pane = Ctx.CreatePane("StepRSI", 25, false, false); Pane.AddList("", rsi, ListStyles.LINE, 0xCC08CC, LineStyles.SOLID, PaneSides.RIGHT); var s = Pane.AddList("StepRSI(" + _RSIperiod.ToString() + "," + _StepSize.ToString() + "," + _Smooth.ToString() + ")", SlowBuffer, ListStyles.LINE, 0x0407BF/*синий*/, LineStyles.SOLID, PaneSides.RIGHT); s.Thickness = 2; } #endregion if (_GetSignals) return TradeSigBuf; return _StepRSIfast ? rsi : SlowBuffer; } public IList Execute(IList source) { return GenStepRSI2(source, Context, RSIperiod, StepSize, Smooth, Chart, GetSignals, Mode1, StepRSIfast); } public IContext Context { get; set; } }