Knowing if the trend is strong enough to support your position is important. The ADX is popular for assessing that. As a result, I made the ADX adaptive using the EhlersAutocorrelationPeriodogram so there is no question as to whether the ADX is set to the right length.
Here is a screenshot. The adaptive ADX is simply displayed here in a label on the top left corner. It also compares the "DI+" to the "DI-" to determine trend direction and color codes the label Green if ADX > 25 and "DI+" > "DI-" or Red ADX > 25 and "DI+" < "DI-". The script can easily be modified to provide a plot of the adaptive ADX values so the trend of ADX values over time can be readily seen.
Here is a screenshot. The adaptive ADX is simply displayed here in a label on the top left corner. It also compares the "DI+" to the "DI-" to determine trend direction and color codes the label Green if ADX > 25 and "DI+" > "DI-" or Red ADX > 25 and "DI+" < "DI-". The script can easily be modified to provide a plot of the adaptive ADX values so the trend of ADX values over time can be readily seen.
CSS:
# Adaptive ADX for ThinOrSwim by Sesqui 29AUG2025
#===========================================================================================================================
script GetCycle {
# Returns the dominant market cycle for use in adaptive indicators
#------------------------------------------
# Charles Schwab & Co. (c) 2016-2025
#
def lag = 48;
def x = EhlersRoofingFilter("cutoff length" = 8, "roof cutoff length" = 48);
def cosinePart = fold i = 3 to 48 with cosPart do cosPart + (3 * (x * GetValue(x, i) + GetValue(x, 1) * GetValue(x, i + 1) + GetValue(x, 2) * GetValue(x, i + 2)) - (x + GetValue(x, 1) + GetValue(x, 2)) * (GetValue(x, i) + GetValue(x, i + 1) + GetValue(x, i + 2))) / Sqrt((3 * (x * x + GetValue(x, 1) * GetValue(x, 1) + GetValue(x, 2) * GetValue(x, 2)) - Sqr(x + GetValue(x, 1) + GetValue(x, 2))) * (3 * (GetValue(x, i) * GetValue(x, i) + GetValue(x, i + 1) * GetValue(x, i + 1) + GetValue(x, i + 2) * GetValue(x, i + 2)) - Sqr(GetValue(x, i) + GetValue(x, i + 1) + GetValue(x, i + 2)))) * Cos(2 * Double.Pi * i / lag);
def sinePart = fold j = 3 to 48 with sinPart do sinPart + (3 * (x * GetValue(x, j) + GetValue(x, 1) * GetValue(x, j + 1) + GetValue(x, 2) * GetValue(x, j + 2)) - (x + GetValue(x, 1) + GetValue(x, 2)) * (GetValue(x, j) + GetValue(x, j + 1) + GetValue(x, j + 2))) / Sqrt((3 * (x * x + GetValue(x, 1) * GetValue(x, 1) + GetValue(x, 2) * GetValue(x, 2)) - Sqr(x + GetValue(x, 1) + GetValue(x, 2))) * (3 * (GetValue(x, j) * GetValue(x, j) + GetValue(x, j + 1) * GetValue(x, j + 1) + GetValue(x, j + 2) * GetValue(x, j + 2)) - Sqr(GetValue(x, j) + GetValue(x, j + 1) + GetValue(x, j + 2)))) * Sin(2 * Double.Pi * j / lag);
def sqSum = Sqr(cosinePart) + Sqr(sinePart);
plot Cycle = ExpAverage(sqSum, 9);
#----------------------------------------------
}# end Script GetCycle{}
#------------------------------------------------
script AdaptiveEMA {
input src = close;
input Cycle = 10;
def length = if IsNaN(Floor(Cycle)) then length[1] else Floor(Cycle);
def ExpMovAvg = src*(2/(1+length))+ExpMovAvg[1]*(1-(2/(1+length)));
plot EMA = ExpMovAvg;
EMA.HideBubble();
}# endScript AdaptiveEMA{}
#------------------------------------------------
#==============================================================================================
def CycleLength = GetCycle().Cycle;
def Length = if IsNaN(Floor(CycleLength)) then Length[1] else Floor(CycleLength);
def hiDiff = high - high[1];
def loDiff = low[1] - low;
def plusDM = if hiDiff > loDiff and hiDiff > 0 then hiDiff else 0;
def minusDM = if loDiff > hiDiff and loDiff > 0 then loDiff else 0;
def ATR = AdaptiveEMA(TrueRange(high, close, low), Length);
def DIp = 100 * AdaptiveEMA(plusDM, Length) / ATR;
def DIm = 100 * AdaptiveEMA(minusDM, Length) / ATR;
def DX = if (DIp + DIm > 0) then 100 * AbsValue(DIp - DIm) / (DIp + DIm) else 0;
def ADX = AdaptiveEMA(DX, Length);
AddLabel(yes, "Adaptive ADX = " + ADX, if ADX >=25 and DIP > DIm then Color.GREEN else if ADX >= 25 and DIp < DIm then Color.RED else if ADX < 25 then Color.WHITE else Color.Current);