/// <summary> /// To handle the input value. /// </summary> /// <param name="input">The input value.</param> /// <returns>The resulting value.</returns> protected override IIndicatorValue OnProcess(IIndicatorValue input) { var macdValue = Macd.Process(input); var signalValue = Macd.IsFormed ? SignalMa.Process(macdValue) : new DecimalIndicatorValue(this, 0); var value = new ComplexIndicatorValue(this); value.InnerValues.Add(Macd, input.SetValue(this, macdValue.GetValue<decimal>() - signalValue.GetValue<decimal>())); value.InnerValues.Add(SignalMa, signalValue); return value; }
/// <summary> /// To handle the input value. /// </summary> /// <param name="input">The input value.</param> /// <returns>The resulting value.</returns> protected override IIndicatorValue OnProcess(IIndicatorValue input) { var candle = input.GetValue<Candle>(); var emaValue = Ema.Process(input.SetValue(this, candle.HighPrice - candle.LowPrice)); if (Ema.IsFormed) { return Roc.Process(emaValue); } return input; }
/// <summary> /// To handle the input value. /// </summary> /// <param name="input">The input value.</param> /// <returns>The resulting value.</returns> protected override IIndicatorValue OnProcess(IIndicatorValue input) { var candle = input.GetValue<Candle>(); if (_previouseClosePrice != null) { var min = _previouseClosePrice.Value < candle.LowPrice ? _previouseClosePrice.Value : candle.LowPrice; var max = _previouseClosePrice.Value > candle.HighPrice ? _previouseClosePrice.Value : candle.HighPrice; input = input.SetValue(this, candle.ClosePrice - min); var p7BpValue = _period7BpSum.Process(input).GetValue<decimal>(); var p14BpValue = _period14BpSum.Process(input).GetValue<decimal>(); var p28BpValue = _period28BpSum.Process(input).GetValue<decimal>(); input = input.SetValue(this, max - min); var p7TrValue = _period7TrSum.Process(input).GetValue<decimal>(); var p14TrValue = _period14TrSum.Process(input).GetValue<decimal>(); var p28TrValue = _period28TrSum.Process(input).GetValue<decimal>(); if (input.IsFinal) _previouseClosePrice = candle.ClosePrice; if (p7TrValue != 0 && p14TrValue != 0 && p28TrValue != 0) { var average7 = p7BpValue / p7TrValue; var average14 = p14BpValue / p14TrValue; var average28 = p28BpValue / p28TrValue; return new DecimalIndicatorValue(this, _stoProcentov * (_weight4 * average7 + _weight2 * average14 + _weight1 * average28) / (_weight4 + _weight2 + _weight1)); } return new DecimalIndicatorValue(this); } if (input.IsFinal) _previouseClosePrice = candle.ClosePrice; return new DecimalIndicatorValue(this); }
/// <inheritdoc /> protected override IIndicatorValue OnProcess(IIndicatorValue input) { var newValue = input.GetValue <decimal>(); if (!_isInitialized) { if (input.IsFinal) { _last = newValue; _isInitialized = true; } return(new DecimalIndicatorValue(this)); } var delta = newValue - _last; var gainValue = _gain.Process(input.SetValue(this, delta > 0 ? delta : 0m)).GetValue <decimal>(); var lossValue = _loss.Process(input.SetValue(this, delta > 0 ? 0m : -delta)).GetValue <decimal>(); if (input.IsFinal) { _last = newValue; } if (lossValue == 0) { return(new DecimalIndicatorValue(this, 100m)); } if (gainValue / lossValue == 1) { return(new DecimalIndicatorValue(this, 0m)); } return(new DecimalIndicatorValue(this, 100m - 100m / (1m + gainValue / lossValue))); }
/// <summary> /// To handle the input value. /// </summary> /// <param name="input">The input value.</param> /// <returns>The resulting value.</returns> protected override IIndicatorValue OnProcess(IIndicatorValue input) { var value = _byPrice(input.GetValue<Candle>()); if (_needAdd) { _buffer.Add(value); _zigZagBuffer.Add(0); } else { _buffer[_buffer.Count - 1] = value; _zigZagBuffer[_zigZagBuffer.Count - 1] = 0; } const int level = 3; int limit = 0, count = 0; while (count < level && limit >= 0) { var res = _zigZagBuffer[limit]; if (res != 0) { count++; } limit--; } limit++; var min = _buffer[limit]; var max = min; int action = 0, j = 0; for (var i = limit + 1; i < _buffer.Count; i++) { if (_buffer[i] > max) { max = _buffer[i]; if (action != 2) //action=1:building the down-point (min) of ZigZag { if (max - min >= _deviation * min) //min (action!=2) end,max (action=2) begin { action = 2; _zigZagBuffer[i] = max; j = i; min = max; } else _zigZagBuffer[i] = 0.0m; //max-min=miser,(action!=2) continue } else //max (action=2) continue { _zigZagBuffer[j] = 0.0m; _zigZagBuffer[i] = max; j = i; min = max; } } else if (_buffer[i] < min) { min = _buffer[i]; if (action != 1) //action=2:building the up-point (max) of ZigZag { if (max - min >= _deviation * max) //max (action!=1) end,min (action=1) begin { action = 1; _zigZagBuffer[i] = min; j = i; max = min; } else _zigZagBuffer[i] = 0.0m; //max-min=miser,(action!=1) continue } else //min (action=1) continue { _zigZagBuffer[j] = 0.0m; _zigZagBuffer[i] = min; j = i; max = min; } } else _zigZagBuffer[i] = 0.0m; } int valuesCount = 0, valueId = 0; decimal last = 0, lastButOne = 0; for (var i = _zigZagBuffer.Count - 1; i > 0 && valuesCount < 2; i--, valueId++) { if (_zigZagBuffer[i] == 0) continue; valuesCount++; if (valuesCount == 1) last = _zigZagBuffer[i]; else lastButOne = _zigZagBuffer[i]; } _needAdd = input.IsFinal; if (valuesCount != 2) return Container.Count > 1 ? this.GetCurrentValue<ShiftedIndicatorValue>() : new ShiftedIndicatorValue(this); if (input.IsFinal) IsFormed = true; CurrentValue = last; return new ShiftedIndicatorValue(this, valueId - 1, input.SetValue(this, lastButOne)); }
/// <summary> /// To handle the input value. /// </summary> /// <param name="input">The input value.</param> /// <returns>The resulting value.</returns> protected override IIndicatorValue OnProcess(IIndicatorValue input) { var candle = input.GetValue<Candle>(); var buffer = input.IsFinal ? _buffer : _buffer.ToList(); buffer.Add(candle); // если буфер стал достаточно большим (стал больше длины) if (buffer.Count > Length) { // Запоминаем интересующие изменения свечек до буфера if (buffer[0].HighPrice > buffer[1].HighPrice) _wasHighDown = true; else if (buffer[0].HighPrice < buffer[1].HighPrice) _wasHighDown = false; if (buffer[0].LowPrice < buffer[1].LowPrice) _wasLowUp = true; else if (buffer[0].LowPrice > buffer[1].LowPrice) _wasLowUp = false; buffer.RemoveAt(0); } // Логика расчета: последующие/предыдущие значения должны быть меньше/больше центрального значения if (buffer.Count >= Length) { // флаги для расчета фракталов (если флаг равен false, то на центральной свече нет фрактала) var isMax = true; var isMin = true; var centerHighPrice = buffer[_numCenter].HighPrice; var centerLowPrice = buffer[_numCenter].LowPrice; for (var i = 0; i < buffer.Count; i++) { if (i == _numCenter) continue; // Все значения до и после центральной свечи должны быть // больше для фрактала вверх и меньше для фрактала вниз if (buffer[i].HighPrice > centerHighPrice) { isMax = false; } if (buffer[i].LowPrice < centerLowPrice) { isMin = false; } } // Фильтр для ситуаций где цена у экстремума одинакова за период больше длины буфера if (isMax && _wasHighDown && buffer.GetRange(0, _numCenter).Min(i => i.HighPrice) == centerHighPrice) { isMax = false; } if (isMin && _wasLowUp && buffer.GetRange(0, _numCenter).Max(i => i.LowPrice) == centerLowPrice) { isMin = false; } var shift = buffer.Count - _numCenter - 1; var upValue = isMax ? new ShiftedIndicatorValue(this, shift, new DecimalIndicatorValue(this, centerHighPrice)) : new ShiftedIndicatorValue(this); var downValue = isMin ? new ShiftedIndicatorValue(this, shift, new DecimalIndicatorValue(this, centerLowPrice)) : new ShiftedIndicatorValue(this); upValue.IsFinal = input.IsFinal; downValue.IsFinal = input.IsFinal; var complexValue = new ComplexIndicatorValue(this); complexValue.InnerValues.Add(Up, Up.Process(upValue)); complexValue.InnerValues.Add(Down, Down.Process(downValue)); return complexValue; } return base.OnProcess(new ShiftedIndicatorValue(this, 0, input.SetValue(this, 0))); }
/// <summary> /// To handle the input value. /// </summary> /// <param name="input">The input value.</param> /// <returns>The resulting value.</returns> protected override IIndicatorValue OnProcess(IIndicatorValue input) { var value = _byPrice(input.GetValue <Candle>()); if (_needAdd) { _buffer.Add(value); _zigZagBuffer.Add(0); } else { _buffer[_buffer.Count - 1] = value; _zigZagBuffer[_zigZagBuffer.Count - 1] = 0; } const int level = 3; int limit = 0, count = 0; while (count < level && limit >= 0) { var res = _zigZagBuffer[limit]; if (res != 0) { count++; } limit--; } limit++; var min = _buffer[limit]; var max = min; int action = 0, j = 0; for (var i = limit + 1; i < _buffer.Count; i++) { if (_buffer[i] > max) { max = _buffer[i]; if (action != 2) //action=1:building the down-point (min) of ZigZag { if (max - min >= _deviation * min) //min (action!=2) end,max (action=2) begin { action = 2; _zigZagBuffer[i] = max; j = i; min = max; } else { _zigZagBuffer[i] = 0.0m; //max-min=miser,(action!=2) continue } } else //max (action=2) continue { _zigZagBuffer[j] = 0.0m; _zigZagBuffer[i] = max; j = i; min = max; } } else if (_buffer[i] < min) { min = _buffer[i]; if (action != 1) //action=2:building the up-point (max) of ZigZag { if (max - min >= _deviation * max) //max (action!=1) end,min (action=1) begin { action = 1; _zigZagBuffer[i] = min; j = i; max = min; } else { _zigZagBuffer[i] = 0.0m; //max-min=miser,(action!=1) continue } } else //min (action=1) continue { _zigZagBuffer[j] = 0.0m; _zigZagBuffer[i] = min; j = i; max = min; } } else { _zigZagBuffer[i] = 0.0m; } } int valuesCount = 0, valueId = 0; decimal last = 0, lastButOne = 0; for (var i = _zigZagBuffer.Count - 1; i > 0 && valuesCount < 2; i--, valueId++) { if (_zigZagBuffer[i] == 0) { continue; } valuesCount++; if (valuesCount == 1) { last = _zigZagBuffer[i]; } else { lastButOne = _zigZagBuffer[i]; } } _needAdd = input.IsFinal; if (valuesCount != 2) { return(Container.Count > 1 ? this.GetCurrentValue <ShiftedIndicatorValue>() : new ShiftedIndicatorValue(this)); } if (input.IsFinal) { IsFormed = true; } CurrentValue = last; return(new ShiftedIndicatorValue(this, valueId - 1, input.SetValue(this, lastButOne))); }
/// <summary> /// To handle the input value. /// </summary> /// <param name="input">The input value.</param> /// <returns>The resulting value.</returns> protected override IIndicatorValue OnProcess(IIndicatorValue input) { var candle = input.GetValue <Candle>(); var buffer = input.IsFinal ? _buffer : _buffer.ToList(); buffer.Add(candle); // если буфер стал достаточно большим (стал больше длины) if (buffer.Count > Length) { // Запоминаем интересующие изменения свечек до буфера if (buffer[0].HighPrice > buffer[1].HighPrice) { _wasHighDown = true; } else if (buffer[0].HighPrice < buffer[1].HighPrice) { _wasHighDown = false; } if (buffer[0].LowPrice < buffer[1].LowPrice) { _wasLowUp = true; } else if (buffer[0].LowPrice > buffer[1].LowPrice) { _wasLowUp = false; } buffer.RemoveAt(0); } // Логика расчета: последующие/предыдущие значения должны быть меньше/больше центрального значения if (buffer.Count >= Length) { // флаги для расчета фракталов (если флаг равен false, то на центральной свече нет фрактала) var isMax = true; var isMin = true; var centerHighPrice = buffer[_numCenter].HighPrice; var centerLowPrice = buffer[_numCenter].LowPrice; for (var i = 0; i < buffer.Count; i++) { if (i == _numCenter) { continue; } // Все значения до и после центральной свечи должны быть // больше для фрактала вверх и меньше для фрактала вниз if (buffer[i].HighPrice > centerHighPrice) { isMax = false; } if (buffer[i].LowPrice < centerLowPrice) { isMin = false; } } // Фильтр для ситуаций где цена у экстремума одинакова за период больше длины буфера if (isMax && _wasHighDown && buffer.GetRange(0, _numCenter).Min(i => i.HighPrice) == centerHighPrice) { isMax = false; } if (isMin && _wasLowUp && buffer.GetRange(0, _numCenter).Max(i => i.LowPrice) == centerLowPrice) { isMin = false; } var shift = buffer.Count - _numCenter - 1; var upValue = isMax ? new ShiftedIndicatorValue(this, shift, new DecimalIndicatorValue(this, centerHighPrice)) : new ShiftedIndicatorValue(this); var downValue = isMin ? new ShiftedIndicatorValue(this, shift, new DecimalIndicatorValue(this, centerLowPrice)) : new ShiftedIndicatorValue(this); upValue.IsFinal = input.IsFinal; downValue.IsFinal = input.IsFinal; var complexValue = new ComplexIndicatorValue(this); complexValue.InnerValues.Add(Up, Up.Process(upValue)); complexValue.InnerValues.Add(Down, Down.Process(downValue)); return(complexValue); } return(base.OnProcess(new ShiftedIndicatorValue(this, 0, input.SetValue(this, 0)))); }