in this indicator there are many input parameter so when i open setting to change them, i get confused because they are too many, can you add heading for each section to seprate them: //@version=5
indicator("CandleSync Analyzer", overlay=true)

// Inputs for time frame visibility
showInTimeFrame1 = input.timeframe("5", title="Show in Time Frame 1")
showInTimeFrame2 = input.timeframe("15", title="Show in Time Frame 2")
showInTimeFrame3 = input.timeframe("30", title="Show in Time Frame 3")

// Calculate body size
bodySize = math.abs(close - open)

// Calculate wick sizes using max function (available from v4 onwards)
upperWick = if open > close
    high - open
else
    high - close

lowerWick = if open > close
    close - low
else
    open - low

// Variables
var int numberOfCandles = input(5, "Number of Candles") // Input for the number of last candles to consider
var float maxVolume = na

// Function to find maximum volume within the specified number of last candles
if bar_index >= numberOfCandles - 1
    maxVolume := volume
    for i = 1 to numberOfCandles - 1
        maxVolume := math.max(maxVolume, volume[i])

// Input parameters for flexibility
shootingStarBodyRatio = input.float(0.35, title="Shooting Star Body Ratio")
shootingStarWickMultiplier = input.float(3, title="Shooting Star Wick Multiplier")
hammerUpperWickRatio = input.float(0.25, title="Hammer Upper Wick Ratio")
hammerBodyRatio = input.float(0.35, title="Hammer Body Ratio")
dojiBodyRatio = input.float(0.05, title="Doji Body Ratio")
dragonflyDojiWickRatio = input.float(0.05, title="Dragonfly Doji Wick Ratio")
gravestoneDojiWickRatio = input.float(0.05, title="Gravestone Doji Wick Ratio")
hangingManBodyRatio = input.float(0.35, title="Hanging Man Body Ratio")
spinningTopBodyRatio = input.float(0.3, title="Spinning Top Body Ratio")
insidePatternBodyRatio = input.float(0.4, title="Inside Pattern Body Ratio")

// Checkboxes to enable/disable each pattern
showShootingStar = input(true, title="Show Shooting Star")
showHammer = input(true, title="Show Hammer")
showInvertedHammer = input(true, title="Show Inverted Hammer")
showDoji = input(true, title="Show Doji")
showDragonflyDoji = input(true, title="Show Dragonfly Doji")
showGravestoneDoji = input(true, title="Show Gravestone Doji")
showHangingMan = input(true, title="Show Hanging Man")
showSpinningTop = input(true, title="Show Spinning Top")
showInsidePattern = input(true, title="Show Inside Pattern")

// Define Candlestick Patterns with refined conditions
isShootingStar = showShootingStar and bodySize < (high - low) * shootingStarBodyRatio and upperWick > lowerWick * shootingStarWickMultiplier and volume == maxVolume
isHammer = showHammer and close > open and (high - close) < (open - low) * hammerUpperWickRatio and bodySize < (high - low) * hammerBodyRatio and volume == maxVolume
isInvertedHammer = showInvertedHammer and open > close and (high - open) < (close - low) * hammerUpperWickRatio and bodySize < (high - low) * hammerBodyRatio and volume == maxVolume
isDoji = showDoji and bodySize <= (high - low) * dojiBodyRatio and math.abs(open - close) <= 0.001 and volume == maxVolume
isDragonflyDoji = showDragonflyDoji and isDoji and close > open and (high - close) < (open - low) * dragonflyDojiWickRatio and volume == maxVolume
isGravestoneDoji = showGravestoneDoji and isDoji and open > close and (high - open) < (close - low) * gravestoneDojiWickRatio and volume == maxVolume
isHangingMan = showHangingMan and isHammer and close < open and bodySize < (high - low) * hangingManBodyRatio and volume == maxVolume
isSpinningTop = showSpinningTop and bodySize < (high - low) * spinningTopBodyRatio and upperWick < (high - low) * spinningTopBodyRatio and lowerWick < (high - low) * spinningTopBodyRatio and volume == maxVolume
isInsidePattern = showInsidePattern and high < high[1] and low > low[1] and bodySize < (high - low) * insidePatternBodyRatio and volume == maxVolume

// Plot the indicator only if it's one of the specified patterns with higher volume and in the specified time frames
plotshape(isHammer and (timeframe.period == showInTimeFrame1 or timeframe.period == showInTimeFrame2 or timeframe.period == showInTimeFrame3), location=location.belowbar, style=shape.labeldown, color=color.red, size=size.small, text="H")
plotshape(isShootingStar and (timeframe.period == showInTimeFrame1 or timeframe.period == showInTimeFrame2 or timeframe.period == showInTimeFrame3), location=location.abovebar, style=shape.labeldown, color=color.red, size=size.small, text="SS")
plotshape(isInvertedHammer and (timeframe.period == showInTimeFrame1 or timeframe.period == showInTimeFrame2 or timeframe.period == showInTimeFrame3), location=location.belowbar, style=shape.labeldown, color=color.red, size=size.small, text="IH")
plotshape(isDoji and (timeframe.period == showInTimeFrame1 or timeframe.period == showInTimeFrame2 or timeframe.period == showInTimeFrame3), location=location.abovebar, style=shape.labeldown, color=color.red, size=size.small, text="D")
plotshape(isDragonflyDoji and (timeframe.period == showInTimeFrame1 or timeframe.period == showInTimeFrame2 or timeframe.period == showInTimeFrame3), location=location.belowbar, style=shape.labeldown, color=color.red, size=size.small, text="DD")
plotshape(isGravestoneDoji and (timeframe.period == showInTimeFrame1 or timeframe.period == showInTimeFrame2 or timeframe.period == showInTimeFrame3), location=location.abovebar, style=shape.labeldown, color=color.red, size=size.small, text="GD")
plotshape(isHangingMan and (timeframe.period == showInTimeFrame1 or timeframe.period == showInTimeFrame2 or timeframe.period == showInTimeFrame3), location=location.belowbar, style=shape.labeldown, color=color.red, size=size.small, text="HM")
plotshape(isSpinningTop and (timeframe.period == showInTimeFrame1 or timeframe.period == showInTimeFrame2 or timeframe.period == showInTimeFrame3), location=location.abovebar, style=shape.labeldown, color=color.red, size=size.small, text="ST")
plotshape(isInsidePattern and (timeframe.period == showInTimeFrame1 or timeframe.period == showInTimeFrame2 or timeframe.period == showInTimeFrame3), location=location.abovebar, style=shape.labeldown, color=color.red, size=size.small, text="IP")

// Alerts
alertcondition((isInsidePattern or isHammer or isShootingStar or isInvertedHammer or isDoji or isDragonflyDoji or isGravestoneDoji or isHangingMan or isSpinningTop) and volume > maxVolume, title='Candlestick Pattern Detected with High Volume', message='A candlestick pattern with high volume has been detected!')


// Weekend and Session Merge

// Input parameters for weekend highlight color
weekendHighlightColor = input.color(color.new(color.red, 90), title="Weekend Highlight Color")
showWeekendLabel = input.bool(true, title="Show Weekend Label")

// Define the weekend start and end times in IST
weekendStartHour = 9
weekendStartMinute = 30
weekendEndHour = 9
weekendEndMinute = 30

// Calculate the weekend start and end timestamps in IST
var int weekendStart = na
var int weekendEnd = na

if dayofweek == dayofweek.friday
    weekendStart := timestamp("Asia/Kolkata", year, month, dayofmonth + 1, weekendStartHour, weekendStartMinute)
else if dayofweek == dayofweek.saturday
    weekendStart := timestamp("Asia/Kolkata", year, month, dayofmonth, weekendStartHour, weekendStartMinute)

if not na(weekendStart)
    weekendEnd := weekendStart + 2 * 86400000

// Highlight the background for the weekend
isWeekend = (time >= weekendStart and time < weekendEnd)
bgcolor(isWeekend ? weekendHighlightColor : na)

// Add "Weekend" label on the chart once
if showWeekendLabel and isWeekend and time == weekendStart
    label.new(bar_index, high, text="Weekend", style=label.style_label_down, color=color.red, textcolor=color.white, size=size.normal)

// Input session times in EST (New York Time) for the first session
startHour1 = input.int(9, title="First Session Start Hour (EST)", minval=0, maxval=23)
startMinute1 = input.int(30, title="First Session Start Minute (EST)", minval=0, maxval=59)
endHour1 = input.int(16, title="First Session End Hour (EST)", minval=0, maxval=23)
endMinute1 = input.int(0, title="First Session End Minute (EST)", minval=0, maxval=59)

// Input session times in IST (Indian Standard Time) for the second session
startHour2 = input.int(19, title="Second Session Start Hour (IST)", minval=0, maxval=23)
startMinute2 = input.int(0, title="Second Session Start Minute (IST)", minval=0, maxval=59)
endHour2 = input.int(23, title="Second Session End Hour (IST)", minval=0, maxval=23)
endMinute2 = input.int(0, title="Second Session End Minute (IST)", minval=0, maxval=59)

sessionColor1 = input.color(color.new(color.green, 90), title="First Session Highlight Color")
sessionColor2 = input.color(color.new(color.red, 90), title="Second Session Highlight Color")

// Calculate the session start and end times in UTC for the first session
sessionStart1 = timestamp("America/New_York", year, month, dayofmonth, startHour1, startMinute1)
sessionEnd1 = timestamp("America/New_York", year, month, dayofmonth, endHour1, endMinute1)

// Calculate the session start and end times in UTC for the second session (IST)
sessionStart2 = timestamp("Asia/Kolkata", year, month, dayofmonth, startHour2, startMinute2)
sessionEnd2 = timestamp("Asia/Kolkata", year, month, dayofmonth, endHour2, endMinute2)

// Highlight background during the first USA session
isInSession1 = (time >= sessionStart1 and time <= sessionEnd1)
bgcolor(isInSession1 ? sessionColor1 : na)

// Highlight background during the second USA session
isInSession2 = (time >= sessionStart2 and time <= sessionEnd2)
bgcolor(isInSession2 ? sessionColor2 : na)

// Support and Resistance Level
// Input parameters
lookbackPeriod = input.int(50, title="Lookback Period for Support/Resistance")
flexibility = input.float(0.01, title="Flexibility Percentage", minval=0.0, step=0.01) / 100
supportRise = input.float(0.5, title="Minimum Green Candle Price Rise (%)", minval=0.0, step=0.1) / 100
resistanceFall = input.float(0.5, title="Minimum Red Candle Price Fall (%)", minval=0.0, step=0.1) / 100
daysToCheck = input.int(1, title="Days to Check for Support/Resistance Level", minval=1)
showSupport = input.bool(true, title="Show Support Levels")
showResistance = input.bool(true, title="Show Resistance Levels")
showBrokenLevels = input.bool(false, title="Show Only Broken Support and Resistance Levels")
maxBrokenTimes = input.int(2, title="Hide Levels Broken More Than N Times", minval=1)

// Time frame inputs
tf1 = input.string("60", title="Time Frame 1")
tf2 = input.string("120", title="Time Frame 2")
tf3 = input.string("240", title="Time Frame 3")
tf4 = input.string("D", title="Time Frame 4")

// Check if current chart's time frame matches any of the specified time frames
showLevels = (timeframe.period == tf1) or (timeframe.period == tf2) or (timeframe.period == tf3) or (timeframe.period == tf4)

// Variables to store support and resistance levels and their broken counts
var float[] supportLevels = na
var int[] supportBrokenCounts = na
var line[] supportLines = na

var float[] resistanceLevels = na
var int[] resistanceBrokenCounts = na
var line[] resistanceLines = na

// Variables to store the latest support and resistance levels for alerts
var float latestSupportLevel = na
var float latestResistanceLevel = na

if showLevels
    // Initialize arrays if they are na
    if na(supportLevels)
        supportLevels := array.new_float()
        supportBrokenCounts := array.new_int()
        supportLines := array.new_line()
    if na(resistanceLevels)
        resistanceLevels := array.new_float()
        resistanceBrokenCounts := array.new_int()
        resistanceLines := array.new_line()
    
    // Ensure we have at least 2 bars of data before proceeding
    if bar_index >= 1

        // Check for support formations
        for i = 1 to lookbackPeriod

            if i > bar_index
                break  // Prevent accessing bars that don't exist

            // Check for support formation
            if close[i] < open[i] and close[i - 1] > open[i - 1] and math.abs(close[i] - open[i - 1]) <= (close[i - 1] * flexibility) and (close[i - 1] - open[i - 1]) >= (open[i - 1] * supportRise) and (timenow - time[i]) <= daysToCheck * 86400000

                supportLevel = close[i]

                // Check if this level is already in the supportLevels array
                isNewLevel = true
                if array.size(supportLevels) > 0
                    for k = 0 to array.size(supportLevels) - 1
                        existingLevel = array.get(supportLevels, k)
                        if math.abs(existingLevel - supportLevel) <= syminfo.mintick * 10
                            isNewLevel := false
                            break
                if isNewLevel
                    array.push(supportLevels, supportLevel)
                    array.push(supportBrokenCounts, 0)
                    // Create line object
                    supportLine = line.new(x1=math.max(0, bar_index - i), y1=supportLevel, x2=bar_index + 100, y2=supportLevel, color=color.green, width=2, extend=extend.right)
                    array.push(supportLines, supportLine)

        // Check for resistance formations
        for i = 1 to lookbackPeriod

            if i > bar_index
                break  // Prevent accessing bars that don't exist

            // Check for resistance formation
            if close[i] > open[i] and close[i - 1] < open[i - 1] and math.abs(close[i] - open[i - 1]) <= (close[i - 1] * flexibility) and (open[i - 1] - close[i - 1]) >= (open[i - 1] * resistanceFall) and (timenow - time[i]) <= daysToCheck * 86400000

                resistanceLevel = close[i]

                // Check if this level is already in the resistanceLevels array
                isNewLevel = true
                if array.size(resistanceLevels) > 0
                    for k = 0 to array.size(resistanceLevels) - 1
                        existingLevel = array.get(resistanceLevels, k)
                        if math.abs(existingLevel - resistanceLevel) <= syminfo.mintick * 10
                            isNewLevel := false
                            break
                if isNewLevel
                    array.push(resistanceLevels, resistanceLevel)
                    array.push(resistanceBrokenCounts, 0)
                    // Create line object
                    resistanceLine = line.new(x1=math.max(0, bar_index - i), y1=resistanceLevel, x2=bar_index + 100, y2=resistanceLevel, color=color.red, width=2, extend=extend.right)
                    array.push(resistanceLines, resistanceLine)

        // Update and draw support levels
        jSupport = array.size(supportLevels) - 1
        while jSupport >= 0

            supportLevel = array.get(supportLevels, jSupport)
            brokenCount = array.get(supportBrokenCounts, jSupport)
            supportLine = array.get(supportLines, jSupport)

            // Check if level is broken
            isBroken = brokenCount > 0

            // Increment broken count if level is broken
            if close < supportLevel and brokenCount < maxBrokenTimes
                brokenCount := brokenCount + 1
                array.set(supportBrokenCounts, jSupport, brokenCount)
                isBroken := true

            // Delete the level if broken more than allowed times
            if brokenCount >= maxBrokenTimes
                line.delete(supportLine)
                array.remove(supportLevels, jSupport)
                array.remove(supportBrokenCounts, jSupport)
                array.remove(supportLines, jSupport)
            else
                // Update line properties based on user inputs
                showLine = showSupport and ((not showBrokenLevels) or (showBrokenLevels and isBroken))
                line.set_extend(supportLine, showLine ? extend.right : extend.none)
                line.set_color(supportLine, showLine ? color.green : color.new(color.green, 100))
                line.set_x2(supportLine, bar_index + 100)

            jSupport := jSupport - 1

        // Update and draw resistance levels
        jResistance = array.size(resistanceLevels) - 1
        while jResistance >= 0

            resistanceLevel = array.get(resistanceLevels, jResistance)
            brokenCount = array.get(resistanceBrokenCounts, jResistance)
            resistanceLine = array.get(resistanceLines, jResistance)

            // Check if level is broken
            isBroken = brokenCount > 0

            // Increment broken count if level is broken
            if close > resistanceLevel and brokenCount < maxBrokenTimes
                brokenCount := brokenCount + 1
                array.set(resistanceBrokenCounts, jResistance, brokenCount)
                isBroken := true

            // Delete the level if broken more than allowed times
            if brokenCount >= maxBrokenTimes
                line.delete(resistanceLine)
                array.remove(resistanceLevels, jResistance)
                array.remove(resistanceBrokenCounts, jResistance)
                array.remove(resistanceLines, jResistance)
            else
                // Update line properties based on user inputs
                showLine = showResistance and ((not showBrokenLevels) or (showBrokenLevels and isBroken))
                line.set_extend(resistanceLine, showLine ? extend.right : extend.none)
                line.set_color(resistanceLine, showLine ? color.red : color.new(color.red, 100))
                line.set_x2(resistanceLine, bar_index + 100)

            jResistance := jResistance - 1

        // Update latest support and resistance levels
        latestSupportLevel := array.size(supportLevels) > 0 ? array.get(supportLevels, array.size(supportLevels) - 1) : na
        latestResistanceLevel := array.size(resistanceLevels) > 0 ? array.get(resistanceLevels, array.size(resistanceLevels) - 1) : na
else
    // If showLevels is false, delete existing lines and reset arrays
    if not na(supportLines)
        for l = 0 to array.size(supportLines) - 1
            lineToDelete = array.get(supportLines, l)
            line.delete(lineToDelete)
        supportLevels := na
        supportBrokenCounts := na
        supportLines := na

    if not na(resistanceLines)
        for l = 0 to array.size(resistanceLines) - 1
            lineToDelete = array.get(resistanceLines, l)
            line.delete(lineToDelete)
        resistanceLevels := na
        resistanceBrokenCounts := na
        resistanceLines := na

    // Reset latest levels
    latestSupportLevel := na
    latestResistanceLevel := na

// Alerts for broken support and resistance levels (must be in global scope)
alertcondition(not na(latestSupportLevel) and close < latestSupportLevel, title="Support Level Broken", message="A support level has been broken.")
alertcondition(not na(latestResistanceLevel) and close > latestResistanceLevel, title="Resistance Level Broken", message="A resistance level has been broken.")