А Чудеса продолжаются!
Оказывается, мало того что ADX(Lua) написан с ошибками, так еще и расчеты отличаются от ADX встроенного в терминал?
Накидал свой вариант, но и он выводит другие значения:
Люди кто знаком с темой подскажите, что не так?
То что должно занимать пять минут, колупаю который день, чай уже давно закончился, да и видимо чаем тут одним не обойтись.
Оказывается, мало того что ADX(Lua) написан с ошибками, так еще и расчеты отличаются от ADX встроенного в терминал?
Накидал свой вариант, но и он выводит другие значения:
Код |
---|
function algorithms.getADX() --[[ Индикатор ADX с +DI и -DI Среда: QUIK, Lua 5.4 По методике Уэллса Уайлдера (period = 14) --]] -- Вспомогательные функции local function sum(t, start_idx, end_idx) local total = 0 for i = start_idx, end_idx do total = total + (t[i] or 0) end return total end local function average(t, start_idx, end_idx) return sum(t, start_idx, end_idx)/(end_idx - start_idx + 1) end -- Локальные буферы для хранения данных local TR, plusDM, minusDM = {}, {}, {} local smoothedTR, smoothedPlusDM, smoothedMinusDM = {}, {}, {} local plusDI, minusDI, DX, ADX = {}, {}, {}, {} local initialized = false -- Флаг инициализации return function (I, Fsettings, ds) local Fsettings = Fsettings or {} local P = Fsettings.Period or 14 -- Период расчета -- Инициализация буферов при первом запуске if I == 1 or not initialized then TR, plusDM, minusDM = {}, {}, {} smoothedTR, smoothedPlusDM, smoothedMinusDM = {}, {}, {} plusDI, minusDI, DX, ADX = {}, {}, {}, {} initialized = true return nil, nil, nil end -- Получение цен текущего и предыдущего бара local high = H(I) or 0 local low = L(I) or 0 local closePrev = C(I-1) or 0 local highPrev = H(I-1) or 0 local lowPrev = L(I-1) or 0 -- 1. Расчет True Range (TR) TR[I] = math.max( high - low, math.abs(high - closePrev), math.abs(low - closePrev) ) -- 2. Расчет Directional Movement (+DM и -DM) local upMove = high - highPrev local downMove = lowPrev - low plusDM[I] = (upMove > downMove and upMove > 0) and upMove or 0 minusDM[I] = (downMove > upMove and downMove > 0) and downMove or 0 -- 3. Сглаживание по методу Уайлдера if I == P then -- Первичное сглаживание (сумма первых P значений) smoothedTR[I] = sum(TR, 2, P) -- TR начинается с 2-го бара smoothedPlusDM[I] = sum(plusDM, 2, P) smoothedMinusDM[I] = sum(minusDM, 2, P) elseif I > P then -- Рекуррентное сглаживание smoothedTR[I] = smoothedTR[I-1] - (smoothedTR[I-1]/P) + TR[I] smoothedPlusDM[I] = smoothedPlusDM[I-1] - (smoothedPlusDM[I-1]/P) + plusDM[I] smoothedMinusDM[I] = smoothedMinusDM[I-1] - (smoothedMinusDM[I-1]/P) + minusDM[I] end -- 4. Расчет Directional Indicators (+DI и -DI) if I >= P and smoothedTR[I] and smoothedTR[I] > 0 then plusDI[I] = 100 * (smoothedPlusDM[I]/smoothedTR[I]) minusDI[I] = 100 * (smoothedMinusDM[I]/smoothedTR[I]) -- 5. Расчет Directional Movement Index (DX) local di_sum = plusDI[I] + minusDI[I] DX[I] = (di_sum ~= 0) and (100 * math.abs(plusDI[I] - minusDI[I])/di_sum) or 0 end -- 6. Расчет ADX (сглаженный DX) if I >= 2*P then if I == 2*P then -- Начальное значение ADX ADX[I] = average(DX, P+1, 2*P) -- Среднее за P периодов else -- Сглаживание методом Уайлдера ADX[I] = (ADX[I-1]*(P-1) + DX[I])/P end end -- Возврат значений (ADX, +DI, -DI) return ADX[I] or nil, plusDI[I] or nil, minusDI[I] or nil end end |
То что должно занимать пять минут, колупаю который день, чай уже давно закончился, да и видимо чаем тут одним не обойтись.
