github.com/influxdata/influxdb/v2@v2.7.6/influxql/query/internal/gota/rsi.go (about)

     1  package gota
     2  
     3  // RSI - Relative Strength Index (http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:relative_strength_index_rsi)
     4  type RSI struct {
     5  	emaUp   EMA
     6  	emaDown EMA
     7  	lastV   float64
     8  }
     9  
    10  // NewRSI constructs a new RSI.
    11  func NewRSI(inTimePeriod int, warmType WarmupType) *RSI {
    12  	ema := NewEMA(inTimePeriod+1, warmType)
    13  	ema.alpha = float64(1) / float64(inTimePeriod)
    14  	return &RSI{
    15  		emaUp:   *ema,
    16  		emaDown: *ema,
    17  	}
    18  }
    19  
    20  // WarmCount returns the number of samples that must be provided for the algorithm to be fully "warmed".
    21  func (rsi RSI) WarmCount() int {
    22  	return rsi.emaUp.WarmCount()
    23  }
    24  
    25  // Warmed indicates whether the algorithm has enough data to generate accurate results.
    26  func (rsi RSI) Warmed() bool {
    27  	return rsi.emaUp.Warmed()
    28  }
    29  
    30  // Last returns the last output value.
    31  func (rsi RSI) Last() float64 {
    32  	return 100 - (100 / (1 + rsi.emaUp.Last()/rsi.emaDown.Last()))
    33  }
    34  
    35  // Add adds a new sample value to the algorithm and returns the computed value.
    36  func (rsi *RSI) Add(v float64) float64 {
    37  	var up float64
    38  	var down float64
    39  	if v > rsi.lastV {
    40  		up = v - rsi.lastV
    41  	} else if v < rsi.lastV {
    42  		down = rsi.lastV - v
    43  	}
    44  	rsi.emaUp.Add(up)
    45  	rsi.emaDown.Add(down)
    46  	rsi.lastV = v
    47  	return rsi.Last()
    48  }