ADX Speed Derivative
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Alphacrafting

// This script calculates the first and second derivates (rates of change) for the ADX indicator,
// displaying each as a non-overlay oscillator with an included midline.

//@version=5
// Administrative Declarations and Inputs
indicator(title="ADX Speed Derivative", shorttitle="ADXSD", format=format.price, precision=4, timeframe="", timeframe_gaps=true)
lensig = input.int(14, title="ADX Smoothing", minval=1, maxval=50)
len = input.int(14, minval=1, title="DI Length")
degree = input.int(1, minval = 1, title = "Derivative Lengths", tooltip = "Sets lookback value for derivatives")

// Calculation of ADX
up = ta.change(high)
down = -ta.change(low)
plusDM = na(up) ? na : (up > down and up > 0 ? up : 0)
minusDM = na(down) ? na : (down > up and down > 0 ? down : 0)
trur = ta.rma(ta.tr, len)
plus = fixnan(100 * ta.rma(plusDM, len) / trur)
minus = fixnan(100 * ta.rma(minusDM, len) / trur)
sum = plus + minus
adx = 100 * ta.rma(math.abs(plus - minus) / (sum == 0 ? 1 : sum), lensig)

// Derivative functions
// NOTE: Derivatives are calculated using the Average Rate Of Change (AROC) model
first_derivative() =>
    aroc = (adx - adx[degree]) / degree
    aroc

second_derivative(first) =>
    aroc = (first - first[degree]) / degree
    aroc

// Assignment of values
first_d  = first_derivative()
second_d = second_derivative(first_d)

// Export to the chart
plot(first_d, color = color.white, title = "1st ADX Derivative", linewidth = 1)
plot(second_d, color = color.purple, title = "2nd ADX Derivative", linewidth = 1)
plot(0, color = color.new(color.white, 70))