Class: DhanHQ::Indicators::RSI

Inherits:
Object
  • Object
show all
Defined in:
lib/DhanHQ/indicators.rb

Overview

Relative Strength Index (RSI)

Momentum oscillator measuring speed and magnitude of price changes.

Examples:

Calculate 14-period RSI

closes = [100, 102, 101, 103, 105, 104, 106, 108, 107, 109, 111, 110, 112, 114, 113]
rsi = DhanHQ::Indicators::RSI.calculate(closes, period: 14)

Class Method Summary collapse

Class Method Details

.calculate(data, period: 14) ⇒ Array<Float>

Calculate RSI for the given data.

Parameters:

  • data (Array<Numeric>)

    Input price data

  • period (Integer) (defaults to: 14)

    Number of periods (default: 14)

Returns:

  • (Array<Float>)

    RSI values (nil for insufficient data points)



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/DhanHQ/indicators.rb', line 85

def self.calculate(data, period: 14)
  return [] if data.nil? || data.empty? || period < 1
  return [] if data.length < period + 1

  # Calculate price changes
  changes = data.each_cons(2).map { |a, b| b - a }

  # Calculate initial average gains and losses
  gains = changes[0...period].select(&:positive?)
  losses = changes[0...period].select(&:negative?).map(&:abs)

  avg_gain = gains.sum.to_f / period
  avg_loss = losses.sum.to_f / period

  rsi_values = Array.new(period, nil)

  # Calculate RSI for first period
  rsi_values << calculate_rsi(avg_gain, avg_loss)

  # Calculate subsequent RSI values
  changes[period..].each do |change|
    gain = change.positive? ? change : 0
    loss = change.negative? ? change.abs : 0

    avg_gain = ((avg_gain * (period - 1)) + gain) / period
    avg_loss = ((avg_loss * (period - 1)) + loss) / period

    rsi_values << calculate_rsi(avg_gain, avg_loss)
  end

  rsi_values
end