Improved AlphaTrend Indicator

stable
By tedo in Trend Published February 2024 👁 877 views 💬 0 comments

Description

The "Improved Alpha Trend Indicator" script integrates advanced techniques like Nadaraya-Watson kernel regression and Optimized Trend Tracker (OTT) calculation to enhance trend analysis and signal generation. Added OTT and NQK (minimized signal Noise), NO need for external dependencies. integrates all necessary functionalities within the script itself, Great for long short entry.
HaasScript
-- Improved AlphaTrend Indicator
DefineCommand("ImprovedAlphaTrend", "Improved AlphaTrend Indicator")

-- Define Parameters
local market = DefineParameter(StringType, "Market", "Market for AlphaTrend", false, PriceMarket())
local interval = DefineParameter(NumberType, "Interval", "Interval for AlphaTrend", false, 0)
local source = DefineParameter(ListNumberType, 'Source', 'Source data for AlphaTrend', false, ClosePrices(interval, true, market), 'ClosePrices, HLPrices, HLCPrices, OHLCPrices')
local alphaTrendLength = DefineParameter(NumberType, "AlphaTrend Length", "Length of AlphaTrend", false, 14)
local alphaTrendMultiplier = DefineParameter(NumberType, "AlphaTrend Multiplier", "Multiplier for AlphaTrend", false, 1)
local novolumedata = DefineParameter(BooleanType, "Change calculation (no volume data)?", "Change calculation (no volume data)?", false, false)
local plot_or_not = DefineParameter(BooleanType, "Draw Plot", "Enable AlphaTrend plot", false, true)
local ottLength = DefineParameter(NumberType, 'OTT Length', 'Period length of OTT', false, 5)
local ottCoefficient = DefineParameter(NumberType, 'OTT Coefficient', 'Coefficient of OTT', false, 0.6)
local maType = DefineParameter(EnumType, 'MA Type', 'MA type of OTT', false, WmaType)

--=========================================================================================================

-- Retrieve High-Speed Price Data
local hsp = CC_HighSpeedPrices(1)
local h = hsp.high
local l = hsp.low
local c  = ( hsp.close+ 2 * hsp.close[2] + 2 * hsp.close[3] + hsp.close[4] ) / 6
-- NQK Parameters
local alpha = DefineParameter(NumberType, 'Alpha', 'NQK Alpha', false, 2)
local nearFactor = DefineParameter(NumberType, 'nearFactor', 'NQK nearFactor', false, 1.5)
local farFactor = DefineParameter(NumberType, 'farFactor', 'NQK farFactor', false, 8)
local atr_length = DefineParameter(NumberType, 'atr_length', 'NQK atr_length', false, 60)
local relative_weight = DefineParameter(NumberType, 'relative_weight', 'NQK relative_weight', false, 8)
local lookback_w = DefineParameter(NumberType, 'lookback_w', 'NQK lookback_w', false, 8)

-- Nadaraya-Watson Kernel Regression Function
local function kernel_regression(_src, _alpha, _r, _h)
    local _currentWeight = 0
    local _cumulativeWeight = 0
    for i = 1, _alpha + 26 do
        local y = _src[i]
        local w = Pow(1 + (Pow(i, 2) / (Pow(_h, 2) * 2 * _r)), -_r)
        _currentWeight = _currentWeight + (y * w)
        _cumulativeWeight = _cumulativeWeight + w
    end
    return _currentWeight / _cumulativeWeight
end

-- Function to Calculate Bounds
local function getBounds(_atr, _nearFactor, _farFactor, _yhat)
    local _upper_far = _yhat + _farFactor * _atr
    local _upper_near = _yhat + _nearFactor * _atr
    local _lower_near = _yhat - _nearFactor * _atr
    local _lower_far = _yhat - _farFactor * _atr
    return {
        upper_near = _upper_near,
        upper_far = _upper_far,
        lower_near = _lower_near,
        lower_far = _lower_far
    }
end

-- Kernel ATR Calculation
local function kernel_atr(_length, _high, _low, _close)
    local trueRange = TRANGE(_high, _low, _close)
    local k_atr = TRIMA (trueRange, _length * 2)
    return k_atr
end



-- Perform Kernel Regression on High-Speed Price Data
local yhat_close = kernel_regression(c, alpha, relative_weight, lookback_w)
local yhat_high = kernel_regression(h, alpha, relative_weight, lookback_w)
local yhat_low = kernel_regression(l, alpha, relative_weight, lookback_w)
local ktr = kernel_atr(atr_length, yhat_high, yhat_low, yhat_close)
local bounds = getBounds(ktr, nearFactor, farFactor, yhat_close)

-- Define Output
local results = {
    kernel_avg = yhat_close,
    upper_near = bounds.upper_near,
    upper_far = bounds.upper_far,
    lower_near = bounds.lower_near,
    lower_far = bounds.lower_far
}

-------------------------------------------------------------------------------------------------------------
-- Define NQK as the price source
local NQK = {}
NQK.close = yhat_close
NQK.high = yhat_high
NQK.low = yhat_low
------------------------------------------------------------------------------------------------------------


-- OTT Calculation Function
local function calculateOTT(yhat_close, len, coef, ma_type, i)
    local avg = ArrayGet(MA(yhat_close, len, ma_type), i or 1)
    local thres = avg * coef * 0.01
    local lowerStop = avg - thres
    local upperStop = avg + thres
    local lowerStopPrev = Load('ott_lsp', lowerStop)
    local upperStopPrev = Load('ott_usp', upperStop)

    -- Calculate lower and upper stops
    lowerStop = (avg > lowerStopPrev) and Max(lowerStop, lowerStopPrev) or lowerStop
    upperStop = (avg < upperStopPrev) and Min(upperStop, upperStopPrev) or upperStop

    -- Direction calculation
    local dir = Load('ott_dir', 1)
    if dir == -1 and avg > upperStopPrev then
        dir = 1
    elseif dir == 1 and avg < lowerStopPrev then
        dir = -1
    end

    Save('ott_lsp', lowerStop)
    Save('ott_usp', upperStop)
    Save('ott_dir', dir)

    local mt = (dir == 1) and lowerStop or upperStop
    local ott = (avg > mt) and mt * (200 + coef) / 200 or mt * (200 - coef) / 200

    return ott
end

----------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------

-- Main AlphaTrend Calculation Logic
OptimizedForInterval(interval, function()
   local high, low, close = NQK.high, NQK.low, NQK.close

    local function updateAlphaTrend(offset)
        offset = offset or 1

        -- AlphaTrend calculations
        local atr = ktr 
        local upThreshold = low[offset] - (atr * alphaTrendMultiplier)
        local downThreshold = high[offset] + (atr * alphaTrendMultiplier)

        local ottValue = calculateOTT(source, ottLength, ottCoefficient, maType, offset)
        local alphaTrend = Load("AlphaTrend", HNC(alphaTrendLength + 1, close[offset]))

        --Integrate OTT value into AlphaTrend calculation
        alphaTrend = ArrayUnshift(alphaTrend, IfElseIf(
            IfElse(novolumedata, RSI(NQK.close, alphaTrendLength)[offset] >= 50, MFI(NQK.high, NQK.low, NQK.close, GetVolume(), alphaTrendLength)[offset] >= 50)
            and upThreshold > alphaTrend[1], downThreshold < alphaTrend[1], ottValue, ottValue, alphaTrend[1])
        )
        alphaTrend = ArrayPop(alphaTrend)

        -- Plotting Logic for regualr alpha trend
        if plot_or_not then
            local a1 = Plot(0, "AlphaTrend1", alphaTrend[1], DarkGreen)
            local a2 = Plot(0, "AlphaTrend2", alphaTrend[2], Red)
            PlotCloud(a1, a2, 21)
        end

        -- Signal Calculation
        local crossCheck = GetCrossOverUnderSignal(alphaTrend[1], alphaTrend[2])
        local alphaCheck = IfElseIf(
            crossCheck == SignalLong and close > alphaTrend,
            crossCheck == SignalShort and close < alphaTrend,
            SignalLong, SignalShort, SignalNone
        )

        local lastSignal = Load('lastSignal', alphaCheck)
        local signalAlpha = (alphaCheck ~= lastSignal and alphaCheck) or SignalNone

        if alphaCheck ~= SignalNone and alphaCheck ~= lastSignal then
            Save('lastSignal', alphaCheck)
        end

        -- Signal Plotting
        if signalAlpha == SignalLong then
            PlotShape(0, ShapeCircle, White, 3, false)
        elseif signalAlpha == SignalShort then
            PlotShape(0, ShapeCircle, Red, 3, true)
        end

       

        DefineOutput(EnumType, signalAlpha, 'Combined Signal (AlphaTrend + OTT)')
        -- Define the AlphaTrend output
       
    end

    -- Warmup Logic
    if Load('warmup') == nil then
        LogWarning('Warming up AlphaTrend...')
        for i = 200, 1, -1 do
            updateAlphaTrend(i)
        end
        LogWarning('Warmup completed.')
        Save('warmup', false)
    else
        updateAlphaTrend() -- Update current step
    end
end)

0 Comments

Sign in to leave a comment.

No comments yet. Be the first!