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.
 
O

oferwo

New member
VIP
Anyone can help with the code to add to this for an audible alert whenever a signal shows up, specifically to "long safe" and "short safe"? Highly appreciate it!

I tried changing this syntax I found
Alert(Bullish_FTR, " ", Alert.Bar, Sound.Chimes); but to no avail!
 
Last edited:
M

mrmac

New member
VIP
Thank you very much for posting this, I have been using it with a fair bit of success for Forex.
Does anyone know if it can be / should be customised for different time frames?
I would really like to understand more about the settings and wondered if the 1min, 5min and 15min (for example) would all require the same settings.
I am finding the ADX very useful and wondered if that in particular would need to be adjusted for the different timeframes?
I am a scalper and take entries on the 1min chart using the psar crossover as my first alert, I then analyse and decide whether to enter or not.
If I understand the DMI and ADX correctly, the green flashes (suggestion to buy) seem to be different shades of green, depending on the "strength" of the move. The same applies to the short signals.
The other question I had was about the "Touching EMA" box, can the EMA be modified to align with the way I interpret the signal / strategy?
Thank you in advance for advice and guidance (y)(y)
 
Thread starter Similar threads Forum Replies Date
H MTF ADX? Questions 2
R Consecutive bar count for DMI and ADX? Questions 0
J CM ADX System for ThinkorSwim Custom 6
H Request: Add arrows and alert to Smart ADX Questions 0
D ADX Cross backtesting strategy Questions 10

Similar threads

Top