Files
QuanTAlib/lib/dynamics/adxr/adxr.pine
T

55 lines
2.8 KiB
Plaintext

// Licensed under the Apache License, Version 2.0
// © mihakralj
//@version=6
indicator("Average Directional Movement Index Rating (ADXR)", "ADXR", overlay=false)
//@function Calculates ADX Rating (ADXR) using current and historical ADX values
//@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)