/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(DataPointBar input) { _trueRange.Update(input); if (Samples == 1) { _previousInput = input; return(50m); } var buyingPressure = new IndicatorDataPoint { Price = input.Close - Math.Min(input.Low, _previousInput.Close) }; _sumBuyingPressure1.Update(buyingPressure); _sumBuyingPressure2.Update(buyingPressure); _sumBuyingPressure3.Update(buyingPressure); _sumTrueRange1.Update(_trueRange.Current); _sumTrueRange2.Update(_trueRange.Current); _sumTrueRange3.Update(_trueRange.Current); _previousInput = input; if (!IsReady) { return(50m); } var average1 = _sumBuyingPressure1 / _sumTrueRange1; var average2 = _sumBuyingPressure2 / _sumTrueRange2; var average3 = _sumBuyingPressure3 / _sumTrueRange3; return(100m * (4 * average1 + 2 * average2 + average3) / 7); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(DataPointBar input) { _tr.Update(input); if (!IsReady) { _atr.Update(input); return(input.Close != 0 ? _atr / input.Close * 100 : 0m); } if (Samples == _period + 1) { // first output value is SMA of TrueRange _atr.Update(input); _lastAtrValue = _atr; } else { // next TrueRange values are smoothed using Wilder's approach _lastAtrValue = (_lastAtrValue * (_period - 1) + _tr) / _period; } return(input.Close != 0 ? _lastAtrValue / input.Close * 100 : 0m); }