/// <summary> /// Computes the next value for this indicator from the given state. /// </summary> /// <param name="input">The TradeBar to this indicator on this time step</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(DataPointBar input) { AverageTrueRange.Update(input); var typicalPrice = (input.High + input.Low + input.Close) / 3m; MiddleBand.Update(input.Occured, input.TimeZone, typicalPrice); // poke the upper/lower bands, they actually don't use the input, they compute // based on the ATR and the middle band LowerBand.Update(input); UpperBand.Update(input); return(MiddleBand); }
/// <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); }