Source: https://fxcodebase.com/code/viewtopic.php?f=17&t=511
Forum: 17 · Topic 511 · 15 post(s)
Nikolay.Gekht · Tue Mar 23, 2010 10:43 am
MT4 and Trading Station of the ADX indicator differs from one implemented in VTTrader. The VTTrader uses the following formula:
Code: Select all `TR = MAX(PREVIOUS CLOSE, CURRENT HIGH) - MIN(PREVIOUS CLOSE, CURRENT LOW) PLUSDM = IF ((CURRENT HIGH > PREVIOUS HIGH AND CURRENT LOW >= PREVIOUS LOW) OR (CURRENT HIGH > PREVIOUS HIGH AND CURRENT LOW < PREVIOUS LOW AND CURRENT HIGH - PREVIOUS HIGH < PREVIOUS LOW - CURRENT LOW) THEN CURRENT HIGH - PREVIOUS HIGH ELSE 0 MINUSDM = IF ((CURRENT HIGH <= PREVIOUS HIGH AND CURRENT LOW < PREVIOUS LOW) OR (CURRENT HIGH > PREVIOUS HIGH AND CURRENT LOW < PREVIOUS LOW AND CURRENT HIGH - PREVIOUS HIGH < PREVIOUS LOW - CURRENT LOW) THEN PREVIOUS LOW - CURRENT LOW ELSE 0
PLUSDI = 100 * WMA(PLUSDM, N1) / WMA(TR, N1) MINUSDI = 100 * WMA(MINUSDM, N1) / WMA(TR, N1)
ADX = 100 * WMA((PLUSDI - MINUSDI) / (PLUSDI + MINUSDI), N2)` where WMA is Wilders Moving Average.
Compare the view of the standard ADX and VT-version of the ADX on the snapshot below:

The VT-like version of the ADX is below:
Please, do not forget to download and install WMA.lua (Wilders Moving Average). This indicator is used by VTADX and, therefore, is required to be installed.
Code: Select all `– Indicator profile initialization routine – Defines indicator profile properties and indicator parameters function Init() indicator:name(“Average Directional Movement Index (VTTrader version)”); indicator:description(“”); indicator:requiredSource(core.Bar); indicator:type(core.Oscillator);
indicator.parameters:addInteger(“SM1”, “Smoothing periods 1”, “No description”, 14, 1, 100); indicator.parameters:addInteger(“SM2”, “Smoothing periods 2”, “No description”, 14, 1, 100); indicator.parameters:addColor(“ADX_color”, “Color of ADX”, “Color of ADX”, core.rgb(255, 0, 0)); end
– Indicator instance initialization routine – Processes indicator parameters and creates output streams – Parameters block local SM1; local SM2;
local first; local firstTR; local firstDI; local source = nil;
– Streams block local TR = nil; local TR_W = nil; local PlusDM = nil; local PlusDM_W = nil; local PlusDI = nil; local MinusDM = nil; local MinusDM_W = nil; local MinusDI = nil; local R = nil; local R_W = nil; local ADX = nil; local H, L, C;
– Routine function Prepare() SM1 = instance.parameters.SM1; SM2 = instance.parameters.SM2; source = instance.source; firstTR = source:first() + 1; H = source.high; L = source.low; C = source.close;
TR = instance:addInternalStream(firstTR, 0); PlusDM = instance:addInternalStream(firstTR, 0); MinusDM = instance:addInternalStream(firstTR, 0);
TR_W = core.indicators:create(“WMA”, TR, SM1); PlusDM_W = core.indicators:create(“WMA”, PlusDM, SM1); MinusDM_W = core.indicators:create(“WMA”, MinusDM, SM1);
firstDI = TR_W.DATA:first();
PlusDI = instance:addInternalStream(firstDI, 0); MinusDI = instance:addInternalStream(firstDI, 0); R = instance:addInternalStream(firstDI, 0);
R_W = core.indicators:create(“WMA”, R, SM2);
first = R_W.DATA:first(); local name = profile:id() .. “(“ .. source:name() .. “, “ .. SM1 .. “, “ .. SM2 .. “)”; instance:name(name); ADX = instance:addStream(“ADX”, core.Line, name, “ADX”, instance.parameters.ADX_color, first); ADX:addLevel(20); end
– Indicator calculation routine function Update(p, mode) if p >= firstTR then local th, tl;
if C[p - 1] > H[p] then th = C[p - 1]; else th = H[p]; end
if C[p - 1] < L[p] then tl = C[p - 1]; else tl = L[p]; end
TR[p] = th - tl;
if H[p] > H[p - 1] and L[p] >= L[p - 1] then PlusDM[p] = H[p] - H[p - 1]; elseif H[p] > H[p - 1] and L[p] < L[p - 1] and ((H[p] - H[p - 1]) > (L[p - 1] - L[p])) then PlusDM[p] = H[p] - H[p - 1]; else PlusDM[p] = 0; end if L[p] < L[p - 1] and H[p] <= H[p - 1] then MinusDM[p] = L[p - 1] - L[p]; elseif L[p] < L[p - 1] and H[p] > H[p - 1] and ((H[p] - H[p - 1]) < (L[p - 1] - L[p])) then MinusDM[p] = L[p - 1] - L[p]; else MinusDM[p] = 0; end end
TR_W:update(mode); PlusDM_W:update(mode); MinusDM_W:update(mode);
if p >= firstDI then PlusDI[p] = 100 * PlusDM_W.DATA[p] / TR_W.DATA[p] MinusDI[p] = 100 * MinusDM_W.DATA[p] / TR_W.DATA[p]
local diff, sum;
diff = math.abs(PlusDI[p] - MinusDI[p]); summ = PlusDI[p] + MinusDI[p]; R[p] = diff / summ; end
R_W:update(mode);
if p >= first then ADX[p] = 100 * R_W.DATA[p]; end end`

The indicator was revised and updated
Nikolay.Gekht · Tue Mar 23, 2010 10:45 am
Overview:
The Average Directional Movement Index (ADX) is a momentum indicator developed by J. Welles Wilder and described in his book “New Concepts in Technical Trading Systems”, written in 1978. The ADX is constructed from two other Wilders’ indicators: the Positive Directional indicator (+DI) and the Negative Directional Indicator (-DI). The +DI and -DI indicators are commonly referred to as the Directional Movement Index. Combining the +/-DI and applying a Wilders() smoothing filter results in the final ADX value.
Interpretation
The ADX’s main purpose is to measure the strength of market trends on a 0-100 scale; the higher the ADX value the stronger the trend. It should be noted that while the direction of price is important to the ADX’s calculation, the ADX itself is not a directional indicator. Values above 40 indicate very strong trending while values below 20 indicate non-trending or ranging market conditions.
Traders typically use the ADX as a filter along with other indicators to create a more concrete trading methodology. Many traders view ADX turning up from below 20 as an early signal of a new emerging trend while, conversely, a declining ADX turning down from above 40 as deterioration of the current trend. Wilder suggests using the ADX as part of a system that includes the +DI and -DI indicators. (See the Directional Movement System indicator for additional details)
Just for reference: VT code
Code: Select all
TH:= if(Ref(C,-1)>H,Ref(C,-1),H);
TL:= if(Ref(C,-1)<L,Ref(C,-1),L);
TR:= TH-TL;
PlusDM:= if(H>Ref(H,-1) AND L>=Ref(L,-1), H-Ref(H,-1), if(H>Ref(H,-1) AND L<Ref(L,-1) AND
H-Ref(H,-1)>Ref(L,-1)-L, H-Ref(H,-1), 0));
PlusDI:= 100 * Wilders(PlusDM,Pr)/Wilders(Tr,Pr);
MinusDM:= if(L<Ref(L,-1) AND H<=Ref(H,-1), Ref(L,-1)-L, if(H>Ref(H,-1) AND L<Ref(L,-1) AND
H-Ref(H,-1)<Ref(L,-1)-L, Ref(L,-1)-L, 0));
MinusDI:= 100 * Wilders(MinusDM,Pr)/Wilders(Tr,Pr);
DIDif:= Abs(PlusDI-MinusDI);
DISum:= PlusDI + MinusDI;
_ADX:= 100 * Wilders(DIDif/DISum,SmPr);
smartfx · Mon May 03, 2010 8:30 am
Is there any possibility to add DMI lines into the same window, using VTTrader version of the formula?
It would be of great benefit!
THANK YOU, IN ADVANCE!!!
Nikolay.Gekht · Tue May 04, 2010 1:29 pm
The VTDMI indicator is here: viewtopic.php?f=17&t=950
To show it on the same area as ADX just go to the “Location” tab of the indicator properties and select the ADX indicator area .
smartfx · Tue May 04, 2010 1:58 pm
WONDERFUL! Great support! THANK YOU SO MUCH!
DS0167 · Fri Jan 07, 2011 2:54 pm
Hello,
Can we get the width and style options added please ? and for the DMI VTTTrader version too ?
Big thank you in advance. And happy new year to the team Danielle
Apprentice · Fri Jan 07, 2011 4:07 pm
Added to developmental cue.
Apprentice · Sat Jan 08, 2011 9:00 am
Style Option Added.
sabrumea · Mon Jan 10, 2011 5:07 am
dear development team, could you guys please help with the signal for VADX?… to make a signal if ADX goes below a certain level.. i have downloaded this indicator together with VDMI you made.. and i found this very reliable tools.. please help with signal
Apprentice · Mon Jan 10, 2011 5:49 am
Added on developmental list.
Apprentice · Thu Apr 21, 2011 6:02 am
Requested can be found here. viewtopic.php?f=29&t=3986
Giantball · Tue Jul 26, 2011 5:12 pm
Hi,
Is it possible to get a 3TF version of ADX VTTrader, just like the 3TF stochs version? thank you for all your help.
Best Regards, G
cc.matt · Sun Jul 15, 2012 8:02 pm
Hi,
Could you create a multi-currency VTADX please?
Thanks, Matt
Apprentice · Wed Apr 12, 2017 6:06 am
Indicator was revised and updated.
Apprentice · Wed Apr 12, 2017 7:57 am
MTF MCP VTADX.lua added.