/// <summary> /// Resets this indicator to its initial state /// </summary> public override void Reset() { _previousInput = null; AverageGain.Reset(); AverageLoss.Reset(); base.Reset(); }
/// <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(IndicatorDataPoint input) { if (_previousInput != null && input.Value >= _previousInput.Value) { AverageGain.Update(input.Time, input.Value - _previousInput.Value); AverageLoss.Update(input.Time, 0m); } else if (_previousInput != null && input.Value < _previousInput.Value) { AverageGain.Update(input.Time, 0m); AverageLoss.Update(input.Time, _previousInput.Value - input.Value); } _previousInput = input; // make sure the difference averages are not negative // (can happen with some types of moving averages -- e.g. DEMA) var averageLoss = AverageLoss < 0 ? 0 : AverageLoss.Current.Value; var averageGain = AverageGain < 0 ? 0 : AverageGain.Current.Value; // Round AverageLoss to avoid computing RSI with very small numbers that lead to overflow exception on the division operation below if (Math.Round(averageLoss, 10) == 0m) { // all up days is 100 return(100m); } var rs = averageGain / averageLoss; return(100m - 100m / (1 + rs)); }
/// <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(IndicatorDataPoint input) { if (_previousInput != null && input.Value >= _previousInput.Value) { AverageGain.Update(input.Time, input.Value - _previousInput.Value); AverageLoss.Update(input.Time, 0m); } else if (_previousInput != null && input.Value < _previousInput.Value) { AverageGain.Update(input.Time, 0m); AverageLoss.Update(input.Time, _previousInput.Value - input.Value); } _previousInput = input; // make sure the difference averages are not negative // (can happen with some types of moving averages -- e.g. DEMA) var averageLoss = AverageLoss < 0 ? 0 : AverageLoss.Current.Value; var averageGain = AverageGain < 0 ? 0 : AverageGain.Current.Value; if (averageLoss == 0m) { // all up days is 100 return(100m); } var rs = averageGain / averageLoss; return(100m - 100m / (1 + rs)); }
/// <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(IndicatorDataPoint input) { if (previousInput != null && input.Value >= previousInput.Value) { AverageGain.Update(input.Time, input.Value - previousInput.Value); AverageLoss.Update(input.Time, 0m); } else if (previousInput != null && input.Value < previousInput.Value) { AverageGain.Update(input.Time, 0m); AverageLoss.Update(input.Time, previousInput.Value - input.Value); } previousInput = input; if (AverageLoss == 0m) { // all up days is 100 return(100m); } var rs = AverageGain / AverageLoss; return(100m - (100m / (1 + rs))); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="time"></param> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override DoubleArray Forward(long time, DoubleArray input) { if (_previousInput != null && input.Value >= _previousInput.Value) { AverageGain.Update(time, input.Value - _previousInput.Value); AverageLoss.Update(time, Constants.Zero); } else if (_previousInput != null && input.Value < _previousInput.Value) { AverageGain.Update(time, Constants.Zero); AverageLoss.Update(time, _previousInput.Value - input.Value); } _previousInput = input; if (AverageLoss == Constants.Zero) { // all up days is 100 return(100.0d); } var rs = AverageGain / AverageLoss; return(100.0d - (100.0d / (1 + rs))); }
/// <summary> /// Resets this indicator to its initial state /// </summary> public override void Reset() { AverageGain.Reset(); AverageLoss.Reset(); base.Reset(); }