Market Structure (DeadCat)

stable
By bIyni3 in Sideways Published August 2025 πŸ‘ 607 views πŸ’¬ 0 comments

Description

Indicator from here: https://www.tradingview.com/script/1nfVAQXp-Market-Structure-DeadCat/ converted to HaasScript by Cosmo. Ill just paste the description from there as well: 🌟 Market Structure (DeadCat) - Indicator Overview 🌟 The Market Structure (DeadCat) indicator plots swing highs and lows (HH, HL, LH, LL) using pivot points, helping you spot uptrends, downtrends, and potential reversals. Perfect for traders who use market structure. 🌟 Key Features 🌟 πŸ”Ή Swing Point Labels HH (Higher High): Signals uptrend strength. HL (Higher Low): Marks bullish support. LH (Lower High): Hints at weakening uptrend or reversal. LL (Lower Low): Confirms downtrend momentum. πŸ”Ή Trend Detection Uptrend: Tracks HH/HL for bullish momentum. Downtrend: Tracks LH/LL for bearish momentum. Waits for breaks of prior HH/HL or LH/LL to confirm new swing points, ensuring reliable signals. πŸ”„
HaasScript
-- Market Structure (DeadCat) Indicator
-- Plots swing highs and lows with HH, HL, LH, LL labels
-- Detects uptrends, downtrends, and potential reversals using pivot points

DefineCommand('MarketStructureDeadCat', 'Market Structure indicator that plots swing highs/lows with trend detection')

-- Define command parameters
local chartIndex = DefineParameter(NumberType, 'chartIndex', 'The chart index to plot on', true, 0, 'Number')
local name = DefineParameter(StringType, 'name', 'Unique name of the indicator', false, 'MS', 'Text')
local interval = DefineParameter(NumberType, 'interval', 'Interval for price data (0 = current)', false, 0, 'Number,InputInterval')

DefineIntervalOptimization(interval)

-- Input parameters
InputGroupHeader('Market Structure Settings')
local pivotLength = Input(name..' Pivot Length', 5, 'Number of bars to look left and right for pivot points')
local showLabels = Input(name..' Show Labels', true, 'Display HH/HL/LH/LL labels on chart')
local showTrendLines = Input(name..' Show Trend Lines', true, 'Draw lines connecting swing points')
local minSwingStrength = Input(name..' Min Swing Strength', 0.1, 'Minimum price difference (%) to validate swing points')

InputGroupHeader('Visual Settings')
local bullishColor = Green
local bearishColor = Red
local neutralColor = Gray

-- Get price data
local high = HighPrices(interval)
local low = LowPrices(interval)
local close = ClosePrices(interval)

-- Initialize persistent variables
local lastSwingHigh = Load(name..'_lastSwingHigh', 0)
local lastSwingLow = Load(name..'_lastSwingLow', 0)
local lastSwingHighIndex = Load(name..'_lastSwingHighIndex', 0)
local lastSwingLowIndex = Load(name..'_lastSwingLowIndex', 0)
local trendDirection = Load(name..'_trendDirection', 0) -- 1 = uptrend, -1 = downtrend, 0 = neutral
local swingHighHistory = Load(name..'_swingHighHistory', {})
local swingLowHistory = Load(name..'_swingLowHistory', {})

-- Function to check if current bar is a pivot high
local function isPivotHigh(index, lookback)
    if index <= lookback or index > (#high - lookback) then
        return false
    end
    
    local currentHigh = high[index]
    
    -- Check left side
    for i = 1, lookback do
        if high[index - i] >= currentHigh then
            return false
        end
    end
    
    -- Check right side
    for i = 1, lookback do
        if high[index + i] >= currentHigh then
            return false
        end
    end
    
    return true
end

-- Function to check if current bar is a pivot low
local function isPivotLow(index, lookback)
    if index <= lookback or index > (#low - lookback) then
        return false
    end
    
    local currentLow = low[index]
    
    -- Check left side
    for i = 1, lookback do
        if low[index - i] <= currentLow then
            return false
        end
    end
    
    -- Check right side
    for i = 1, lookback do
        if low[index + i] <= currentLow then
            return false
        end
    end
    
    return true
end

-- Function to calculate percentage difference
local function percentDifference(value1, value2)
    if value2 == 0 then return 0 end
    return Abs((value1 - value2) / value2 * 100)
end

-- Function to determine swing point type
local function getSwingType(isHigh, currentValue, lastValue, trend)
    if isHigh then
        if lastValue == 0 then
            return "H", neutralColor -- First high
        elseif currentValue > lastValue then
            return trend == 1 and "HH" or "LH", trend == 1 and bullishColor or bearishColor
        else
            return "LH", bearishColor
        end
    else -- is Low
        if lastValue == 0 then
            return "L", neutralColor -- First low
        elseif currentValue < lastValue then
            return trend == -1 and "LL" or "HL", trend == -1 and bearishColor or bullishColor
        else
            return "HL", bullishColor
        end
    end
end

-- Main logic - scan for pivot points
local currentIndex = #high - pivotLength
local signal = SignalNone

if currentIndex > pivotLength then
    -- Check for pivot high
    if isPivotHigh(currentIndex, pivotLength) then
        local currentHigh = high[currentIndex]
        local strengthCheck = lastSwingHigh == 0 or percentDifference(currentHigh, lastSwingHigh) >= minSwingStrength
        
        if strengthCheck then
            local swingType, color = getSwingType(true, currentHigh, lastSwingHigh, trendDirection)
            
            -- Update trend based on swing type
            if swingType == "HH" or (swingType == "HL" and trendDirection ~= -1) then
                trendDirection = 1 -- Uptrend
            elseif swingType == "LH" then
                trendDirection = -1 -- Potential downtrend
            end
            
            -- Store swing high data
            lastSwingHigh = currentHigh
            lastSwingHighIndex = currentIndex
            
            -- Add to history (keep last 10 swings)
            ArrayAdd(swingHighHistory, {price = currentHigh, index = currentIndex, type = swingType})
            if #swingHighHistory > 10 then
                ArrayShift(swingHighHistory)
            end
            
            -- Plot swing high
            if showLabels then
                PlotShape(chartIndex, ShapeTriangleDown, color, 8, true, swingType, White)
            end
            
            -- Generate signal
            if swingType == "LH" and trendDirection == -1 then
                signal = SignalShort
            elseif swingType == "HH" and trendDirection == 1 then
                signal = SignalLong
            end
            
            Log("Swing High detected: " .. swingType .. " at " .. Round(currentHigh, 6))
        end
    end
    
    -- Check for pivot low
    if isPivotLow(currentIndex, pivotLength) then
        local currentLow = low[currentIndex]
        local strengthCheck = lastSwingLow == 0 or percentDifference(currentLow, lastSwingLow) >= minSwingStrength
        
        if strengthCheck then
            local swingType, color = getSwingType(false, currentLow, lastSwingLow, trendDirection)
            
            -- Update trend based on swing type
            if swingType == "LL" or (swingType == "LH" and trendDirection ~= 1) then
                trendDirection = -1 -- Downtrend
            elseif swingType == "HL" then
                trendDirection = 1 -- Potential uptrend
            end
            
            -- Store swing low data
            lastSwingLow = currentLow
            lastSwingLowIndex = currentIndex
            
            -- Add to history (keep last 10 swings)
            ArrayAdd(swingLowHistory, {price = currentLow, index = currentIndex, type = swingType})
            if #swingLowHistory > 10 then
                ArrayShift(swingLowHistory)
            end
            
            -- Plot swing low
            if showLabels then
                PlotShape(chartIndex, ShapeTriangleUp, color, 8, false, swingType, White)
            end
            
            -- Generate signal
            if swingType == "HL" and trendDirection == 1 then
                signal = SignalLong
            elseif swingType == "LL" and trendDirection == -1 then
                signal = SignalShort
            end
            
            Log("Swing Low detected: " .. swingType .. " at " .. Round(currentLow, 6))
        end
    end
end

-- Draw trend lines if enabled
if showTrendLines and #swingHighHistory >= 2 then
    local lastTwo = {swingHighHistory[#swingHighHistory-1], swingHighHistory[#swingHighHistory]}
    -- Note: Trend line drawing between specific points is limited in HaasScript
    -- This is a simplified representation
end

-- Plot trend direction indicator
local trendValue = trendDirection
Plot(chartIndex + 1, name..' Trend', trendValue, 
     trendDirection == 1 and bullishColor or (trendDirection == -1 and bearishColor or neutralColor))

-- Plot zero line for trend indicator
PlotHorizontalLine(chartIndex + 1, 'Zero Line', Gray, 0, Dashed)
PlotHorizontalLine(chartIndex + 1, 'Bullish', bullishColor, 1, Solid)
PlotHorizontalLine(chartIndex + 1, 'Bearish', bearishColor, -1, Solid)

-- Save persistent data
Save(name..'_lastSwingHigh', lastSwingHigh)
Save(name..'_lastSwingLow', lastSwingLow)
Save(name..'_lastSwingHighIndex', lastSwingHighIndex)
Save(name..'_lastSwingLowIndex', lastSwingLowIndex)
Save(name..'_trendDirection', trendDirection)
Save(name..'_swingHighHistory', swingHighHistory)
Save(name..'_swingLowHistory', swingLowHistory)

-- Custom reporting
Finalize(function()
    local trendText = trendDirection == 1 and "UPTREND" or (trendDirection == -1 and "DOWNTREND" or "NEUTRAL")
    CustomReport('Current Trend', trendText, 'Market Structure')
    CustomReport('Last Swing High', Round(lastSwingHigh, 6), 'Market Structure')
    CustomReport('Last Swing Low', Round(lastSwingLow, 6), 'Market Structure')
    CustomReport('Swing Highs Detected', #swingHighHistory, 'Market Structure')
    CustomReport('Swing Lows Detected', #swingLowHistory, 'Market Structure')
end)

-- Return the signal
DefineOutput(EnumType, signal, 'Market Structure Signal (Long/Short/None)', 'TradeBotContainer, IndicatorContainer, Signal Helpers')

0 Comments

Sign in to leave a comment.

No comments yet. Be the first!