// The MIT License (MIT) // © mihakralj //@version=6 indicator("Average Directional Movement Index Rating (ADXR)", "ADXR", overlay=false) //@function Calculates ADX Rating (ADXR) using current and historical ADX values //@doc https://github.com/mihakralj/pinescript/blob/main/indicators/dynamics/adxr.md //@param period Number of bars used in ADX calculation //@param rating_period Number of bars between current and historical ADX //@returns tuple of ADXR value, ADX value, +DI, -DI adxr(simple int period, simple int rating_period) => if period <= 0 runtime.error("Period must be greater than 0") if rating_period <= 0 runtime.error("Rating period must be greater than 0") var float EPSILON = 1e-10 float alpha = 1.0/float(period) float tr = na(close[1]) ? high - low : math.max(high - low, math.max(math.abs(high - close[1]), math.abs(low - close[1]))) float plus_dm = na(high[1]) ? 0.0 : high - high[1] > low[1] - low and high - high[1] > 0 ? high - high[1] : 0.0 float minus_dm = na(low[1]) ? 0.0 : low[1] - low > high - high[1] and low[1] - low > 0 ? low[1] - low : 0.0 var float e = 1.0 var float tr_raw = na tr_raw := na(tr_raw) ? tr : (tr_raw * (period - 1) + tr) / period float tr_smooth = e > EPSILON ? tr_raw / (1.0 - e) : tr_raw var float pdm_raw = na pdm_raw := na(pdm_raw) ? plus_dm : (pdm_raw * (period - 1) + plus_dm) / period float plus_dm_smooth = e > EPSILON ? pdm_raw / (1.0 - e) : pdm_raw var float mdm_raw = na mdm_raw := na(mdm_raw) ? minus_dm : (mdm_raw * (period - 1) + minus_dm) / period float minus_dm_smooth = e > EPSILON ? mdm_raw / (1.0 - e) : mdm_raw float plus_di = tr_smooth != 0.0 ? math.min(100 * plus_dm_smooth / tr_smooth, 50.0) : 0.0 float minus_di = tr_smooth != 0.0 ? math.min(100 * minus_dm_smooth / tr_smooth, 50.0) : 0.0 float dx = plus_di + minus_di != 0.0 ? 100 * math.abs(plus_di - minus_di) / (plus_di + minus_di) : 0.0 var float adx_raw = na adx_raw := na(adx_raw) ? 0.0 : (adx_raw * (period - 1) + dx) / period float adx_value = e > EPSILON ? adx_raw / (1.0 - e) : adx_raw e *= (1 - alpha) float historical_adx = adx_value[math.min(rating_period, bar_index)] float adxr_value = (adx_value + nz(historical_adx,0)) / 2.0 [adxr_value, adx_value, plus_di, minus_di] // ---------- Main loop ---------- // Inputs i_period = input.int(14, "ADX Period", minval=1, tooltip="Number of bars used in ADX calculation") i_rating_period = input.int(14, "Rating Period", minval=1, tooltip="Number of bars between current and historical ADX") // Calculate ADXR [adxr_value, adx_value, plus_di, minus_di] = adxr(i_period, i_rating_period) // Plot plot(adxr_value, "ADXR", color=color.yellow, linewidth=2) plot(adx_value, "ADX", color=color.yellow, linewidth=2) plot(plus_di, "+DI", color=color.yellow, linewidth=2) plot(minus_di, "-DI", color=color.yellow, linewidth=2)