Class RsiRTIndicator

All Implemented Interfaces:
ClockAware, Resettable, CacheableRTIndicator, RTIndicator

public class RsiRTIndicator extends AbstractDecorableIncrementalRTIndicator implements CacheableRTIndicator
RSI RTIndicator

RSI = 100 - 100 / (1 + RS) with RS = averageGain / averageLoss. The averages are those of a simple moving average by default (sma = true, Cutler's RSI: the gain and loss averages are the block averages of SmaRTIndicator, refreshed at the end of each period of periods ticks) or Wilder's smoothing (sma = false, MmaRTIndicator, what TA-Lib and ta4j compute).

When there is nothing to divide. The formula is undefined when the averages are both 0 (no gain and no loss in the window: the price did not move) and Wilder does not say what to return. This indicator follows TA-Lib and ta4j, which the accuracy tests of this repository compare it with:

  • no gain and no loss: 0;
  • gains and no loss: 100;
  • losses and no gain: 0.
Other libraries choose differently for the first case (the Python ta, technicalindicators and trading-signals return 100, finta returns NaN), so a value read as "oversold" or "overbought" says nothing on a series that does not move: a rule such as rsi < 30 fires on a flat market. What follows from it:
  • a series that has never moved reads 0;
  • with sma = true, a rise followed by a plateau reads 100 until the first whole period without a gain ends, and 0 from then on;
  • with sma = false, the average gain only decays, never reaching 0 in practice, so the same plateau stays at 100.
In the cases above getRelativeStrength() holds the value that was returned (0 or 100), not a ratio. The tests testNoMovement... pin all of this.
  • Constructor Details

    • RsiRTIndicator

      public RsiRTIndicator()
    • RsiRTIndicator

      public RsiRTIndicator(int periods)
    • RsiRTIndicator

      public RsiRTIndicator(int periods, boolean sma)
    • RsiRTIndicator

      public RsiRTIndicator(int periods, RTIndicator indicator)
    • RsiRTIndicator

      public RsiRTIndicator(int periods, RTIndicator indicator, boolean sma)
      Creates an RSI indicator with configurable averaging method. When sma=true, uses SMA for gain/loss averaging (Cutler's RSI variant). When sma=false, uses MMA (Modified Moving Average, equivalent to Wilder's smoothing). Each gain/loss average wraps its own GainRTIndicator/LossRTIndicator to extract positive/negative price changes from the input stream.
      Parameters:
      periods - number of periods for the averaging window
      indicator - optional decorated indicator to pre-process input values
      sma - true for SMA-based averaging, false for MMA-based (Wilder's)
  • Method Details

    • reset

      public void reset()
      Specified by:
      reset in interface Resettable
      Overrides:
      reset in class AbstractDecorableIncrementalRTIndicator
    • getRelativeStrength

      public double getRelativeStrength()
    • signature

      public String signature()
      Periods, averaging variant and source chain.

      The variant is read back off the averaging indicator that was actually built rather than off a remembered constructor flag — Cutler's (SMA) and Wilder's (MMA) RSI produce different series for the same periods, and the object is the honest witness to which one this is.

      Specified by:
      signature in interface CacheableRTIndicator
      Returns:
      the identity, or null when this instance cannot state one (an unidentifiable source, a mode the implementation does not model) and must therefore compute live
    • initValue

      protected double initValue(double initValue)
      Description copied from class: AbstractIncrementalRTIndicator
      Non periodic init value
      Overrides:
      initValue in class AbstractIncrementalRTIndicator
      Parameters:
      initValue -
      Returns:
    • getPrevValue

      protected double getPrevValue()
      Overrides:
      getPrevValue in class AbstractIncrementalRTIndicator
    • nextValue

      protected double nextValue(double prevValue, double newValue)
      Computes the RSI value using the standard formula: RSI = 100 - (100 / (1 + RS)), where RS (Relative Strength) = averageGain / averageLoss. Handles edge cases: returns 0 when both are zero, 100 when only loss is zero (pure uptrend), 0 when only gain is zero (pure downtrend).
      Overrides:
      nextValue in class AbstractDecorableIncrementalRTIndicator
      Parameters:
      prevValue - the previous raw input value (used by gain/loss sub-indicators)
      newValue - the current raw input value
      Returns:
      RSI value in the range [0, 100]
    • toString

      protected com.google.common.base.MoreObjects.ToStringHelper toString(com.google.common.base.MoreObjects.ToStringHelper ts)
      Overrides:
      toString in class AbstractRTIndicator