The MT4 and FXCM Trading Station DMI (Directional Movement Index) implementation uses EMA smoothing instead of Wilder's smoothing.
This is the implementation of the DMI indicator on the base of Wilders smoothing.
See ADX VTTrader version topic for more details about the algorithms.
Download the indicator:
This indicator uses WMA indicator. Please, do not forget to download and install it. Find the WMA indicator here: WMA (Wilder's moving average).
- Code: Select all
-- Indicator profile initialization routine
-- Defines indicator profile properties and indicator parameters
-- TODO: Add minimal and maximal value of numeric parameters and default color of the streams
function Init()
indicator:name("Directional Movement Index (VTTrader version)");
indicator:description("");
indicator:requiredSource(core.Bar);
indicator:type(core.Oscillator);
indicator.parameters:addGroup("Calculation");
indicator.parameters:addInteger("N", "Number of periods", "", 14, 1, 1000);
indicator.parameters:addGroup("Style");
indicator.parameters:addColor("clrDIP", "Color of DI+", "", core.rgb(0, 183, 183));
indicator.parameters:addColor("clrDIM", "Color of DI-", "", core.rgb(219, 64, 0));
end
-- Indicator instance initialization routine
-- Processes indicator parameters and creates output streams
-- TODO: Refine the first period calculation for each of the output streams.
-- TODO: Calculate all constants, create instances all subsequent indicators and load all required libraries
-- Parameters block
local N;
local first;
local firstTR;
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 H, L, C;
local DIP = nil;
local DIM = nil;
-- Routine
function Prepare()
N = instance.parameters.N;
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, N);
PlusDM_W = core.indicators:create("WMA", PlusDM, N);
MinusDM_W = core.indicators:create("WMA", MinusDM, N);
first = TR_W.DATA:first();
local name = profile:id() .. "(" .. source:name() .. ", " .. N .. ")";
instance:name(name);
DIP = instance:addStream("DIP", core.Line, name .. ".DIP", "DI+", instance.parameters.clrDIP, first)
DIM = instance:addStream("DIM", core.Line, name .. ".DIM", "DI-", instance.parameters.clrDIM, first)
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 >= first then
DIP[p] = 100 * PlusDM_W.DATA[p] / TR_W.DATA[p]
DIM[p] = 100 * MinusDM_W.DATA[p] / TR_W.DATA[p]
end
end
Simple VTDMI based strategy.
viewtopic.php?f=31&t=65666&p=117209#p117209
The indicator was revised and updated