Hammond B3's ADX for ThinkorSwim

T

tomsk

Well-known member
VIP
To enable easier search, I have relocated this cool ADX label indicator from Hammond B3 here. Merry Xmas folks

Code:
## HAMMOND B3'S "B3_ADX"
##
## This study is based on several ADX theories by several traders combined.
## HAMMOND B3 didn't come up with the methodology for the formula,
## merely combined the logic of several others into one easy to use study.
#---
### DIRECTIONS FOR USE ::
## 1) LABEL BOXES POPUP AND TELL YOU WHAT TO DO (or think about), THOUGH TWO BOXES PERMANENTLY EXIST
##        a. A MODE BOX THAT TELLS YOU THE STUDY'S CURRENT DIRECTIONAL BIAS, IF ANY
##        b. TREND DECAY IS TELLING YOU HOW MUCH THE TREND HAS WEAKEND
##            (0% = STRONGLY TRENDING & -100% = TREND IS OVER & NO TREND IS POSSIBLE)
##            (Brighter the Box = Stronger the Trend)
## 2) BIG ARROWS MEAN THE SAFEST "WITH THE TREND" ENTRIES (DURING LONG/SHORT MODES) (no gaurantees)
## 3) SMALL GRAY ARROWS DURING SCALP MODE FOR WEAK TRENDS OR NO CONFIRMED TREND (riskier but sometimes trend starters)
## 4) SQUARES MEAN SCALE OR EXIT IF YOU WISH NOT TO BE GREEDY OR DO NOTHING (profit early and often method)
## 5) MAGENTA TRIANGLES ARE A POINT OF DECISION, CHOOSE:
##        a. EXIT (AGAIN FOR THE NOT SO GREEDY AND IS THE RISK ADVERSE CHOICE)
##        b. ADD (TRENDS TEND TO CONTINUE RATHER THAN REVERSE, FOR THE AGGRESSIVE POSSITION BUILDERS)
##        c. BET AGAINST THE TREND (FOR EARLIEST REVERSAL ENTRY, !ADVANCED TRADERS ONLY!)
##        d. DO NOTHING (WAIT FOR NEXT EXIT DECISION)
## 6) BOXES POPUP SOMETIMES GIVING INFORMATION:
##        a. WHEN DIRECTIONAL DOMINANCE IS CHANGING
##            (if staying on trend is important, this is an exit if the signal goes against you)
##        b. WHEN REVERSAL RISK IS HIGH (be cautious as no definite directional dominance exists)
##        c. DURING DIRECTIONAL BREAKOUT OF THE INDICATOR
##            (breakout of trend; trade entry if price is also breaking the corresponding new Hi or Lo)
##        d. WHEN A TREND COMES TO AN END  (yellow dot)
##          (the risk adverse trader would want to exit here, others begin considering scalp mode)
## 7) THE 20 BAR EXPONENTIAL MOVING AVERAGE IS USED TO GIVE A POSSIBLE BETTER VALUED ENTRY
##        BOX APPEARS WHEN THE DOMINANCE OF ONE DIRECTION IS PRESENT BUT PRICE IS ON OPPOSITE SIDE OF EMA (or touching)
##        (ADVANCED TRADERS WILL WAIT FOR THE TOUCH OF 20ema BEFORE ENTRY, YOU CAN MISS OPPORTUNIES WAITING)
##        (By this method, enter trade upon popup of 20ema box AFTER & IF the MATCHING red/green arrow LAST signaled)
#---
## /ENJOY!


declare upper;

## DMI/ADX ::
input ADXMA = 13;
input length = 8;
input averageType = AverageType.WILDERS;
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 = MovingAverage(averageType, TrueRange(high, close, low), length);
def "DI+" = 100 * MovingAverage(averageType, plusDM, length) / ATR;
def "DI-" = 100 * MovingAverage(averageType, minusDM, length) / ATR;
def DX = if ("DI+" + "DI-" > 0) then 100 * AbsValue("DI+" - "DI-") / ("DI+" + "DI-") else 0;
def ADX = MovingAverage(averageType, DX, ADXma);
def ADXHIGH = Highest(ADX, 50);
## /END DMI/ADX

## / BEGIN TREND CONSTITUTE ::
input trendconstitute = 25;
def xline = trendconstitute;

## /END TREND CONSTITUTE

## BEGIN MODE SETTINGS ::
def longmode = ADX > trendconstitute and "DI+" > "DI-";
def shortmode = ADX > trendconstitute and "DI+" < "DI-";
def scalplong = ADX <= trendconstitute and "DI+" > "DI-" and "DI+" > trendconstitute;
def scalpshort = ADX <= trendconstitute and "DI+" < "DI-" and "DI-" > trendconstitute;
AddLabel( yes , if longmode then "ADXBullMode" else
                    if shortmode then "ADXBearMode" else
                    if scalplong then "ADXScalp-LMode" else
                    if scalpshort then "ADXScalp-SMode" else
                    "No-Man's Land",
                        if longmode and ((1 - (ADX - trendconstitute) / (ADXHIGH - trendconstitute)) * -100) > -50 then Color.UPTICK else
                        if longmode and ((1 - (ADX - trendconstitute) / (ADXHIGH - trendconstitute)) * -100) <= -50 then Color.dark_green else
                        if shortmode and ((1 - (ADX - trendconstitute) / (ADXHIGH - trendconstitute)) * -100) > -50 then Color.DOWNTICK else 
                        if shortmode and ((1 - (ADX - trendconstitute) / (ADXHIGH - trendconstitute)) * -100) <= -50 then Color.dark_red else 
                        if scalplong then Color.LIGHT_GREEN else
                        if scalpshort then Color.PINK else Color.GRAY);
## /END MODES

## BEGIN SIGNALS
input noisefilter = 20.1;
input scaling = 45;
input countertrend = 10;
plot longsafe = if (ADX > trendconstitute and "DI+" > "DI-" and  "DI+"[1] <= "DI-"[1] and "DI-" <= noisefilter
                                          and AbsValue("DI+" - "DI-") > 5.5)
                or (ADX > trendconstitute and ADX[1] <= trendconstitute and "DI+" > "DI-" and "DI-" <= noisefilter
                                          and AbsValue("DI+" - "DI-") > 5.5)
                or ("DI+" > trendconstitute and "DI+"[1] <= trendconstitute and ADX > trendconstitute
                                            and "DI-" <= noisefilter and AbsValue("DI+" - "DI-") > 5.5)
                or (ADX > trendconstitute and "DI+"[1] > "DI-"[1] and "DI+"[2] <= "DI-"[2] and "DI-"[1] >= noisefilter
                                          and AbsValue("DI+" - "DI-") > 5.5 and "DI+" > trendconstitute)
                then Low else Double.NaN;
plot longscalp = if  ADX <= trendconstitute and "DI+" > "DI-" and "DI+" > trendconstitute and "DI+"[1] <= trendconstitute
                 then Low else Double.NaN;
plot shortsafe = if (ADX > trendconstitute and "DI+" < "DI-" and  "DI+"[1] >= "DI-"[1]
                                           and "DI+" <= noisefilter and AbsValue("DI+" - "DI-") > 5.5)
                 or (ADX > trendconstitute and ADX[1] <= trendconstitute and "DI+" < "DI-" and "DI+" <= noisefilter
                                           and AbsValue("DI+" - "DI-") > 5.5)
                 or ("DI-" > trendconstitute and "DI-"[1] <= trendconstitute and ADX > trendconstitute
                                             and "DI+" <= noisefilter and AbsValue("DI+" - "DI-") > 5.5)
                 or (ADX > trendconstitute and "DI+"[1] < "DI-"[1] and "DI+"[2] >= "DI-"[2] and "DI+"[1] >= noisefilter
                                           and AbsValue("DI+" - "DI-") > 5.5 and "DI-" > trendconstitute)
                 then High else Double.NaN;
plot shortscalp = if ADX <= trendconstitute and "DI+" < "DI-" and "DI-" > trendconstitute
                                            and "DI-"[1] <= trendconstitute then High else Double.NaN;
plot counterlong = if "DI+" crosses above countertrend then Low else Double.NaN;
plot countershort = if "DI-" crosses above countertrend then High else Double.NaN;
plot scalelong = if "DI+" crosses below scaling then high else Double.NaN;
plot scaleshort = if "DI-" crosses below scaling then low else Double.NaN;
plot trendend = if ADX crosses below trendconstitute then Open else double.nan;
longsafe.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
longsafe.setdefaultColor(Color.UPTICK);
longsafe.SetLineWeight(2);
longscalp.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
longscalp.setdefaultColor(Color.GRAY);
longscalp.SetLineWeight(1);
shortsafe.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
shortsafe.setdefaultColor(Color.DOWNTICK);
shortsafe.SetLineWeight(2);
shortscalp.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
shortscalp.setdefaultColor(Color.GRAY);
shortscalp.SetLineWeight(1);
counterlong.SetPaintingStrategy(PaintingStrategy.LINE_VS_TRIANGLES);
counterlong.setdefaultColor(Color.MAGENTA);
counterlong.SetLineWeight(5);
countershort.SetPaintingStrategy(PaintingStrategY.LINE_VS_TRIANGLES);
countershort.setdefaultColor(Color.MAGENTA);
countershort.SetLineWeight(5);
scalelong.SetPaintingStrategy(PaintingStrategy.SQUARES);
scalelong.setdefaultColor(Color.LIGHT_GREEN);
scalelong.SetLineWeight(5);
scaleshort.SetPaintingStrategy(PaintingStrategy.SQUARES);
scaleshort.setdefaultColor(Color.PINK);
scaleshort.SetLineWeight(5);
trendend.SetPaintingStrategy(PaintingStrategy.points);
trendend.setdefaultColor(createColor(206, 207, 0));
trendend.SetLineWeight(5);
AddCloud(if "DI+" > "DI-" and ADX > trendconstitute then high else Double.NaN, high + ATR, Color.GREEN, Color.green);
AddCloud(if "DI+" < "DI-" and ADX > trendconstitute then low else Double.NaN, low - ATR, Color.RED, Color.red);
AddLabel( yes , if (ADX > trendconstitute and "DI+" > "DI-" and  "DI+"[1] <= "DI-"[1] and "DI-" <= noisefilter
                                          and AbsValue("DI+" - "DI-") > 5.5)
                or (ADX > trendconstitute and ADX[1] <= trendconstitute and "DI+" > "DI-" and "DI-" <= noisefilter
                                          and AbsValue("DI+" - "DI-") > 5.5)
                or ("DI+" > trendconstitute and "DI+"[1] <= trendconstitute and ADX > trendconstitute
                                            and "DI-" <= noisefilter and AbsValue("DI+" - "DI-") > 5.5)
                or (ADX > trendconstitute and "DI+"[1] > "DI-"[1] and "DI+"[2] <= "DI-"[2] and "DI-"[1] >= noisefilter
                                          and AbsValue("DI+" - "DI-") > 5.5 and "DI+" > trendconstitute) then "ADX L-Entry"
            else if ADX <= trendconstitute and "DI+" > "DI-" and "DI+" > trendconstitute and "DI+"[1] <= trendconstitute then "ADX L-Scalp"
            else if (ADX > trendconstitute and "DI+" < "DI-" and  "DI+"[1] >= "DI-"[1]
                                           and "DI+" <= noisefilter and AbsValue("DI+" - "DI-") > 5.5)
                 or (ADX > trendconstitute and ADX[1] <= trendconstitute and "DI+" < "DI-" and "DI+" <= noisefilter
                                           and AbsValue("DI+" - "DI-") > 5.5)
                 or ("DI-" > trendconstitute and "DI-"[1] <= trendconstitute and ADX > trendconstitute
                                             and "DI+" <= noisefilter and AbsValue("DI+" - "DI-") > 5.5)
                 or (ADX > trendconstitute and "DI+"[1] < "DI-"[1] and "DI+"[2] >= "DI-"[2] and "DI+"[1] >= noisefilter
                                           and AbsValue("DI+" - "DI-") > 5.5 and "DI-" > trendconstitute) then "ADX S-Entry"
            else if ADX <= trendconstitute and "DI+" < "DI-" and "DI-" > trendconstitute
                                            and "DI-"[1] <= trendconstitute then "ADX S-Scalp"
            else if "DI+" crosses above countertrend then "ADX Countertrend+ Exit, Add Short or Counter Long"
            else if "DI-" crosses above countertrend then "ADX Countertrend- Exit, Add Long or Counter Short"
            else if "DI+" crosses below scaling then "ADX Scale Long"
            else if "DI-" crosses below scaling then "ADX Scale Short"
            else "ADX Hold",
            if (ADX > trendconstitute and "DI+" > "DI-" and  "DI+"[1] <= "DI-"[1] and "DI-" <= noisefilter
                                          and AbsValue("DI+" - "DI-") > 5.5)
                or (ADX > trendconstitute and ADX[1] <= trendconstitute and "DI+" > "DI-" and "DI-" <= noisefilter
                                          and AbsValue("DI+" - "DI-") > 5.5)
                or ("DI+" > trendconstitute and "DI+"[1] <= trendconstitute and ADX > trendconstitute
                                            and "DI-" <= noisefilter and AbsValue("DI+" - "DI-") > 5.5)
                or (ADX > trendconstitute and "DI+"[1] > "DI-"[1] and "DI+"[2] <= "DI-"[2] and "DI-"[1] >= noisefilter
                                          and AbsValue("DI+" - "DI-") > 5.5 and "DI+" > trendconstitute) then color.green
            else if ADX <= trendconstitute and "DI+" > "DI-" and "DI+" > trendconstitute and "DI+"[1] <= trendconstitute then color.light_green
            else if (ADX > trendconstitute and "DI+" < "DI-" and  "DI+"[1] >= "DI-"[1]
                                           and "DI+" <= noisefilter and AbsValue("DI+" - "DI-") > 5.5)
                 or (ADX > trendconstitute and ADX[1] <= trendconstitute and "DI+" < "DI-" and "DI+" <= noisefilter
                                           and AbsValue("DI+" - "DI-") > 5.5)
                 or ("DI-" > trendconstitute and "DI-"[1] <= trendconstitute and ADX > trendconstitute
                                             and "DI+" <= noisefilter and AbsValue("DI+" - "DI-") > 5.5)
                 or (ADX > trendconstitute and "DI+"[1] < "DI-"[1] and "DI+"[2] >= "DI-"[2] and "DI+"[1] >= noisefilter
                                           and AbsValue("DI+" - "DI-") > 5.5 and "DI-" > trendconstitute) then color.red
            else if ADX <= trendconstitute and "DI+" < "DI-" and "DI-" > trendconstitute
                                            and "DI-"[1] <= trendconstitute then color.pink
            else if "DI+" crosses above countertrend then color.magenta
            else if "DI-" crosses above countertrend then color.magenta
            else if "DI+" crosses below scaling then color.Dark_Green
            else if "DI-" crosses below scaling then color.dark_red
            else createcolor(30, 110, 190));

def reversal = if highest(adx, adxma) < 25 then 1 else 0;
AddLabel( if reversal > 0 then yes else no, if reversal > 0 then "Reversal Warning!" else ":",
                if reversal > 0 then color.YELLOW else color.gray);
AddLabel( if trendend then yes else no, if trendend then "End of Trend!" else ":",
                if trendend then color.YELLOW else color.gray);
## /END SIGNALS

## BEGIN HIGH PASSING ::
def diuphi = Highest("DI+", 30);
def didnhi = Highest("DI-", 30);
# moved up :: def ADXHIGH = Highest(ADX, 50);

def decay = (1 - (ADX - trendconstitute) / (ADXHIGH - trendconstitute)) * 100;
AddLabel( yes , if ADX > 25 and decay <= 0 then "TRENDING!"
            else if ADX > 25 then
            AsText((1 - (ADX - trendconstitute) / (ADXHIGH - trendconstitute)) * -100, NumberFormat.TWO_DECIMAL_PLACES) + "%TrendDecay" 
            else "No Trend",
            if ADX <= 25 then createcolor(90, 90, 90)
            else if decay <= 1 then createcolor(0, 233, 254)
            else if decay <= 23.6 then  createcolor(0, 195, 220)
            else if decay <= 38.2 then  createcolor(0, 163, 200)
            else if decay <= 50 then  createcolor(20, 147, 170)
            else if decay <= 61.8 then  createcolor(45, 132, 160)
            else if decay <= 78.6 then  createcolor(70, 120, 150)
            else if decay > 61.8 then  createcolor(100, 110, 140)     
            else Color.GRAY);
AddLabel( yes , if "DI+" - diuphi >= 0 and "DI+" > trendconstitute then "DMI +Break+"
            else if "DI-" - didnhi >= 0 and "DI-" > trendconstitute then "DMI -Break-"
            else if "DI+" > didnhi and "DI+"[1] <= didnhi[1] then "+Dominance+"
            else if "DI-" > diuphi and "DI-"[1] <= diuphi[1] then "-Dominance-"
            else ":",
            if "DI+" - diuphi >= 0 and "DI+" > trendconstitute then Color.GREEN
            else if "DI-" - didnhi >= 0 and "DI-" > trendconstitute then Color.RED
            else if "DI+" > didnhi and "DI+"[1] <= didnhi[1] then Color.uptick
            else if "DI-" > diuphi and "DI-"[1] <= diuphi[1] then color.downtick
            else Color.dark_Gray);
## /END HIGH PASSING

## BEGIN EXPONENTIAL MA BIAS ::
def x = close;
def twentyema = expAverage(close, 20);
AddLabel( YES , if AbsValue(close - twentyema) <= .0149 then "Touching EMA @" + round(twentyema,2)
                      else if ADX > trendconstitute and "DI+" > "DI-" and close <= twentyema then "L-Value @" + round(twentyema,2)
                      else if ADX > trendconstitute and "DI+" < "DI-" and close >= twentyema then "S-Value @" + round(twentyema,2)
                      else "20ema=" + astext(twentyema),
                      if ADX > trendconstitute and "DI+" > "DI-" and close <= twentyema then createcolor(10, 220, 43)
                      else if ADX > trendconstitute and "DI+" < "DI-" and close >= twentyema then createcolor(220, 10, 43)
                      else if ADX > trendconstitute and "DI+" > "DI-" then createcolor(50, 100, 53)
                      else if ADX > trendconstitute and "DI+" < "DI-" then createcolor(100, 50, 53)
                      else color.gray);
## /END EXPONENTIAL MA BIAS
## /END STUDY
 
Last edited:
markos

markos

Well-known member
VIP
Thanks @tomsk I put that in my notepad++.
Hammond B3 has come up with some really cool stuff.
We appreciate your contributions to the community!!
 
P

Playstation

Active member
VIP
I understand tom is away for now, does anyone knows what does Point 6 "BOXES POPUP" mean?
 
Last edited:
T

Trader Raider

Member
VIP
@Playstation, it just means that sometimes an alert label will briefly appear. For example, "End of Trend!" just popped up on my 3-minute /RTY chart.
 
Top