//@version=6
indicator('Liquidity Lines & Sweeps + FVG [Lucien] with VWAP', overlay = true, max_lines_count = 500)

// === LIQUIDITY SETTINGS ===
liquidityBool = input.bool(true, 'Show Liquidity Sweeps', group = 'Liquidity Settings')
liquidity_len = input.int(15, 'Liquidity Length', minval = 5, group = 'Liquidity Settings')
upColor = input.color(color.new(color.yellow, 15), title = 'Bullish Liquidity Color', group = 'Liquidity Settings')
downColor = input.color(color.new(color.yellow, 15), title = 'Bearish Liquidity Color', group = 'Liquidity Settings')

// === EMA SETTINGS ===
showEma = input.bool(false, title="Show EMA", group="Moving Average")
emaLength = input.int(50, title="EMA Length", minval=1, group="Moving Average")      // Changed EMA1 default to 50
emaSource = input.source(close, title="EMA Source", group="Moving Average")
emaTimeframe = input.timeframe("", title="EMA Timeframe (leave empty for current)", group="Moving Average")
emaColor = input.color(color.new(color.green, 0), title="EMA Color", group="Moving Average")
emaWidth = input.int(1, title="EMA Line Width", minval=1, maxval=5, group="Moving Average")

// === EMA 2 SETTINGS ===
showEma2 = input.bool(false, title="Show EMA 2", group="Moving Average")               // Enabled by default
ema2Length = input.int(100, title="EMA 2 Length", minval=1, group="Moving Average")
ema2Source = input.source(close, title="EMA 2 Source", group="Moving Average")
ema2Timeframe = input.timeframe("", title="EMA 2 Timeframe (leave empty for current)", group="Moving Average")
ema2Color = input.color(color.new(color.blue, 0), title="EMA 2 Color", group="Moving Average")
ema2Width = input.int(1, title="EMA 2 Line Width", minval=1, maxval=5, group="Moving Average")

// === EMA 3 SETTINGS ===
showEma3 = input.bool(false, title="Show EMA 3", group="Moving Average")               // Enabled by default
ema3Length = input.int(200, title="EMA 3 Length", minval=1, group="Moving Average")
ema3Source = input.source(close, title="EMA 3 Source", group="Moving Average")
ema3Timeframe = input.timeframe("", title="EMA 3 Timeframe (leave empty for current)", group="Moving Average")
ema3Color = input.color(color.new(color.red, 0), title="EMA 3 Color", group="Moving Average")
ema3Width = input.int(1, title="EMA 3 Line Width", minval=1, maxval=5, group="Moving Average")

// --- VWAP SETTINGS ---
showVWAP = input.bool(false, "Show VWAP", group = "VWAP Settings")
vwapColor = input.color(color.new(color.orange, 0), "VWAP Color", group = "VWAP Settings")
vwapWidth = input.int(2, "VWAP Line Width", minval = 1, maxval = 5, group = "VWAP Settings")

// Calculate EMA 1 with timeframe option
emaValue = request.security(syminfo.tickerid, emaTimeframe != "" ? emaTimeframe : timeframe.period, ta.ema(emaSource, emaLength))
plot(showEma ? emaValue : na, title="EMA", color=emaColor, linewidth=emaWidth)

// Calculate EMA 2 with timeframe option
emaValue2 = request.security(syminfo.tickerid, ema2Timeframe != "" ? ema2Timeframe : timeframe.period, ta.ema(ema2Source, ema2Length))
plot(showEma2 ? emaValue2 : na, title="EMA 2", color=ema2Color, linewidth=ema2Width)

// Calculate EMA 3 with timeframe option
emaValue3 = request.security(syminfo.tickerid, ema3Timeframe != "" ? ema3Timeframe : timeframe.period, ta.ema(ema3Source, ema3Length))
plot(showEma3 ? emaValue3 : na, title="EMA 3", color=ema3Color, linewidth=ema3Width)

// --- VWAP calculation & plot ---
vwapValue = ta.vwap
plot(showVWAP ? vwapValue : na, title="VWAP", color=vwapColor, linewidth=vwapWidth)

// --- True range for label positioning ---
tr = ta.tr(true)

// --- Bias Detection for EMA (no chart labels now) ---
bullishBias = (emaValue > emaValue2) and (emaValue2 > emaValue3) and (close > emaValue3)
bearishBias = (emaValue < emaValue2) and (emaValue2 < emaValue3) and (close < emaValue3)

// === FVG SETTINGS ===
isFvgToShow =  input(true, title='Display FVG', group="Fair Value Gap")
bullishFvgColor = input.color(color.new(color.green, 50), 'Bullish FVG Color', group="Fair Value Gap")
bearishFvgColor = input.color(color.new(color.red, 50), 'Bearish FVG Color', group="Fair Value Gap")
mitigatedFvgColor = input.color(color.new(color.gray, 50), 'Mitigated FVG Color', group="Fair Value Gap")
fvgHistoryNbr = input.int(5, 'Number of FVG to show', minval=1, maxval=50, group="Fair Value Gap")
isMitigatedFvgToReduce = input(false, title='Reduce mitigated FVG', group="Fair Value Gap")

// === DATA STRUCTURES ===
// For Liquidity
type liquidity
    float value
    int barStart
    int barEnd
    line liquidityLine
    bool broken
    label sweep

var array<liquidity> bullishLiquidity = array.new<liquidity>()
var array<liquidity> bearishLiquidity = array.new<liquidity>()

// For FVG
var array<box>  fvgBoxes = array.new_box(0)
var array<bool> fvgTypes = array.new_bool(0)
var array<label> fvgLabels = array.new_label(0)
var array<bool> isFvgMitigated = array.new_bool(0)

// === FVG FUNCTIONS ===
FVGDraw(_boxes, _fvgTypes, _isFvgMitigated, _fvgLabels) => 
    for [index, value] in _boxes
        // Processing bullish FVG
        if array.get(_fvgTypes, index)
            if low <= box.get_bottom(value)
                array.remove(_boxes, index)
                array.remove(_fvgTypes, index)
                array.remove(_isFvgMitigated, index)
                label.delete(array.get(_fvgLabels, index))
                array.remove(_fvgLabels, index)
                box.delete(value)
            else 
                if low < box.get_top(value)
                    box.set_bgcolor(value, mitigatedFvgColor)    
                    if not array.get(_isFvgMitigated, index)
                        alert("FVG has been mitigated", alert.freq_once_per_bar)
                        array.set(_isFvgMitigated, index, true)
                    if isMitigatedFvgToReduce
                        box.set_top(value, low)
                box.set_right(value, bar_index)
                label.set_x(array.get(_fvgLabels, index), (box.get_left(value) + box.get_right(value)) / 2 )
                label.set_y(array.get(_fvgLabels, index), box.get_top(value) - (box.get_top(value) - box.get_bottom(value)) / 2)
        // Processing bearish FVG
        else
            if high >= box.get_top(value)
                array.remove(_boxes, index)
                array.remove(_fvgTypes, index)
                array.remove(_isFvgMitigated, index)
                label.delete(array.get(_fvgLabels, index))
                array.remove(_fvgLabels, index)
                box.delete(value)
            else
                if high > box.get_bottom(value)
                    box.set_bgcolor(value, mitigatedFvgColor)    
                    if not array.get(_isFvgMitigated, index)
                        alert("FVG has been mitigated", alert.freq_once_per_bar)
                        array.set(_isFvgMitigated, index, true)
                    if isMitigatedFvgToReduce
                        box.set_bottom(value, high)
                box.set_right(value, bar_index)
                label.set_x(array.get(_fvgLabels, index), (box.get_left(value) + box.get_right(value)) / 2 )
                label.set_y(array.get(_fvgLabels, index), box.get_top(value) - (box.get_top(value) - box.get_bottom(value)) / 2)

// === LIQUIDITY DETECTION ===
phLiquidity = ta.pivothigh(high, liquidity_len, liquidity_len)
plLiquidity = ta.pivotlow(low, liquidity_len, liquidity_len)

if not na(phLiquidity) and liquidityBool
    liquidity newLiquidity = liquidity.new()
    newLiquidity.value := high[liquidity_len]
    newLiquidity.barStart := time[liquidity_len]
    newLiquidity.barEnd := time
    newLiquidity.broken := false
    newLiquidity.liquidityLine := line.new(x1 = newLiquidity.barStart, y1 = newLiquidity.value, x2 = newLiquidity.barEnd, y2 = newLiquidity.value, xloc = xloc.bar_time, color = downColor, width = 1)
    array.push(bearishLiquidity, newLiquidity)
    if array.size(bearishLiquidity) > 7
        deletedLiquidity = array.shift(bearishLiquidity)
        deletedLiquidity.liquidityLine.delete()

if not na(plLiquidity) and liquidityBool
    liquidity newLiquidity = liquidity.new()
    newLiquidity.value := low[liquidity_len]
    newLiquidity.barStart := time[liquidity_len]
    newLiquidity.barEnd := time
    newLiquidity.broken := false
    newLiquidity.liquidityLine := line.new(x1 = newLiquidity.barStart, y1 = newLiquidity.value, x2 = newLiquidity.barEnd, y2 = newLiquidity.value, xloc = xloc.bar_time, color = upColor, width = 1)
    array.push(bullishLiquidity, newLiquidity)
    if array.size(bullishLiquidity) > 7
        deletedLiquidity = array.shift(bullishLiquidity)
        deletedLiquidity.liquidityLine.delete()

// === FVG DETECTION ===
isBullishFVG = high[3] < low[1]
isBearishFVG = low[3] > high[1]

if isBullishFVG and isFvgToShow
    box _box = box.new(left=bar_index - 2, top=low[1], right=bar_index - 1, bottom=high[3], border_style=line.style_solid, border_width=1, bgcolor=bullishFvgColor, border_color=color.new(color.green, 100))
    label _label = label.new(math.ceil((_box.get_left() + _box.get_right()) / 2), _box.get_top() - (_box.get_top() - _box.get_bottom()) / 2, text = ".", style = label.style_none, textcolor = color.rgb(0, 0, 0))     
    array.push(fvgBoxes, _box)
    array.push(fvgTypes, true)
    array.push(isFvgMitigated, false)
    array.push(fvgLabels, _label)

    if array.size(fvgBoxes) > fvgHistoryNbr + 1
        box.delete(array.get(fvgBoxes, 0))
        label.delete(array.get(fvgLabels, 0))
        array.remove(fvgLabels, 0)
        array.remove(fvgBoxes, 0)
        array.remove(fvgTypes, 0)
        array.remove(isFvgMitigated, 0)

if isBearishFVG and isFvgToShow
    box _box = box.new(left=bar_index - 2, top=low[3], right=bar_index - 1, bottom=high[1], border_style=line.style_solid, border_width=1, bgcolor=bearishFvgColor, border_color=color.new(color.red, 100))
    label _label = label.new(math.ceil((_box.get_left() + _box.get_right()) / 2), _box.get_top() - (_box.get_top() - _box.get_bottom()) / 2, text = ".", style = label.style_none, textcolor = color.rgb(0, 0, 0))     
    array.push(fvgBoxes, _box)
    array.push(fvgTypes, false)
    array.push(isFvgMitigated, false)
    array.push(fvgLabels, _label)

    if array.size(fvgBoxes) > fvgHistoryNbr + 1
        box.delete(array.get(fvgBoxes, 0))
        label.delete(array.get(fvgLabels, 0))
        array.remove(fvgLabels, 0)
        array.remove(fvgBoxes, 0)
        array.remove(fvgTypes, 0)
        array.remove(isFvgMitigated, 0)

// === UPDATE VISUALS ===
// Update Liquidity Lines and Sweeps
var bool sweepAlert = false

if array.size(bearishLiquidity) > 0
    liquidity testLiquidity = na
    for i = array.size(bearishLiquidity) - 1 to 0 by 1
        testLiquidity := array.get(bearishLiquidity, i)
        if high > testLiquidity.value
            testLiquidity.liquidityLine.set_x2(time)
            testLiquidity.liquidityLine.set_style(line.style_dashed)
            array.remove(bearishLiquidity, i)
            if close < testLiquidity.value
                testLiquidity.sweep := label.new(x = time, y = high, text = 'x', xloc = xloc.bar_time, style = label.style_label_down, size = size.normal, textcolor = color.new(color.purple, 0), color = color.new(color.white, 100))
                sweepAlert := true
        else
            testLiquidity.liquidityLine.set_x2(time)

if array.size(bullishLiquidity) > 0
    liquidity testLiquidity = na
    for i = array.size(bullishLiquidity) - 1 to 0 by 1
        testLiquidity := array.get(bullishLiquidity, i)
        if low < testLiquidity.value
            testLiquidity.liquidityLine.set_x2(time)
            testLiquidity.liquidityLine.set_style(line.style_dashed)
            array.remove(bullishLiquidity, i)
            if close > testLiquidity.value
                testLiquidity.sweep := label.new(x = time, y = low, text = 'x', xloc = xloc.bar_time, style = label.style_label_up, size = size.normal, textcolor = color.new(color.teal, 0), color = color.new(color.white, 100))
                sweepAlert := true
        else
            testLiquidity.liquidityLine.set_x2(time)

// Update FVGs
FVGDraw(fvgBoxes, fvgTypes, isFvgMitigated, fvgLabels)

// === ALERTS ===
alertcondition(sweepAlert, title = "Liquidity Sweep", message = "A liquidity zone has been swept.")
sweepAlert := false


// === PREVIOUS DAY HIGH/LOW SETTINGS ===
showPrevDayRange = input.bool(true, 'Show Previous Day High/Low', group='Previous Day Range')
prevDayColorHigh = input.color(color.new(color.red, 0), 'Previous Day High Color', group='Previous Day Range')
prevDayColorLow = input.color(color.new(color.red, 0), 'Previous Day Low Color', group='Previous Day Range')
prevDayLineWidth = input.int(1, 'Previous Day Line Width', minval=1, maxval=5, group='Previous Day Range')
prevDayLineStyle = input.string('Dashed', 'Previous Day Line Style', options=['Dashed', 'Dotted'], group='Previous Day Range')

// Convert line style string to line.style constant
lineStyle = prevDayLineStyle == 'Dotted' ? line.style_dotted : line.style_dashed

// Get previous day timeframe string or use 'D'
dailyTF = "D"  // fixed daily timeframe

// Request previous daily data (high/low) and previous day start timestamp (session start)
prevDayHigh = request.security(syminfo.tickerid, dailyTF, high[1], lookahead=barmerge.lookahead_on)
prevDayLow = request.security(syminfo.tickerid, dailyTF, low[1], lookahead=barmerge.lookahead_on)
prevDayTime = request.security(syminfo.tickerid, dailyTF, time[1], lookahead=barmerge.lookahead_on)  // Timestamp of previous daily bar start

// Variables to hold lines just once (persistent)
var line prevHighLine = na
var line prevLowLine = na

// Calculate approximate timeframe minutes and future time offset
tf_minutes = timeframe.multiplier * (timeframe.isintraday ? 1 : 1440)
futureBarsCount = 500
futureDeltaMs = tf_minutes * 60000 * futureBarsCount
lineEndTime = time + futureDeltaMs

if showPrevDayRange
    if na(prevHighLine)
        prevHighLine := line.new(x1=prevDayTime, y1=prevDayHigh, x2=lineEndTime, y2=prevDayHigh, xloc=xloc.bar_time, color=prevDayColorHigh, width=prevDayLineWidth, style=lineStyle)
    else
        line.set_xy1(prevHighLine, prevDayTime, prevDayHigh)
        line.set_xy2(prevHighLine, lineEndTime, prevDayHigh)

    if na(prevLowLine)
        prevLowLine := line.new(x1=prevDayTime, y1=prevDayLow, x2=lineEndTime, y2=prevDayLow, xloc=xloc.bar_time, color=prevDayColorLow, width=prevDayLineWidth, style=lineStyle)
    else
        line.set_xy1(prevLowLine, prevDayTime, prevDayLow)
        line.set_xy2(prevLowLine, lineEndTime, prevDayLow)
else
    if not na(prevHighLine)
        line.delete(prevHighLine)
        prevHighLine := na
    if not na(prevLowLine)
        line.delete(prevLowLine)
        prevLowLine := na

//------------------------------------------------------------------------------
// Settings
//-----------------------------------------------------------------------------{
// Session A
show_sesa = input.bool(true, '', inline='sesa', group='Session A')
sesa_txt = input.string('New York', '', inline='sesa', group='Session A')
sesa_ses = input.session('1500-1730', '', inline='sesa', group='Session A')
sesa_css = input.color(#ff5d00, '', inline='sesa', group='Session A')

// Session B
show_sesb = input.bool(true, '', inline='sesb', group='Session B')
sesb_txt = input.string('London', '', inline='sesb', group='Session B')
sesb_ses = input.session('1000-1300', '', inline='sesb', group='Session B')
sesb_css = input.color(#2157f3, '', inline='sesb', group='Session B')

// Session C
show_sesc = input.bool(false, '', inline='sesc', group='Session C')
sesc_txt = input.string('Tokyo', '', inline='sesc', group='Session C')
sesc_ses = input.session('0000-0900', '', inline='sesc', group='Session C')
sesc_css = input.color(#e91e63, '', inline='sesc', group='Session C')

// Session D
show_sesd = input.bool(true, '', inline='sesd', group='Session D')
sesd_txt = input.string('Asia', '', inline='sesd', group='Session D')
sesd_ses = input.session('0100-0700', '', inline='sesd', group='Session D')
sesd_css = input.color(#ffeb3b, '', inline='sesd', group='Session D')

// Timezones
tz_incr = input.int(3, 'UTC (+/-)', group='Timezone')
use_exchange = input.bool(false, 'Use Exchange Timezone', group='Timezone')

// Ranges Options
bg_transp = input.float(10, 'Range Area Transparency', group='Ranges Settings')
show_outline = input.bool(true, 'Range Outline', group='Ranges Settings')
show_txt = input.bool(true, 'Range Label', group='Ranges Settings')

//-----------------------------------------------------------------------------}

// Functions
//-----------------------------------------------------------------------------{
n = bar_index

get_range(session, session_name, session_css) =>
    var t = 0
    var max = high
    var min = low
    var box bx = na
    var label lbl = na
    
    if session > session[1]
        t := time
        max := high
        min := low
        bx := box.new(n, max, n, min, bgcolor=color.new(session_css, 100 - bg_transp), border_color=show_outline ? session_css : na, border_style=line.style_dotted)
        if show_txt
            lbl := label.new(t, max, session_name, xloc=xloc.bar_time, textcolor=session_css, style=label.style_label_down, color=color.new(color.white, 100), size=size.tiny)
    
    // Fixed boolean condition
    if session == 1 and session == session[1]
        max := math.max(high, max)
        min := math.min(low, min)
        box.set_top(bx, max)
        box.set_rightbottom(bx, n, min)
        if show_txt
            label.set_xy(lbl, int(math.avg(t, time)), max)
//-----------------------------------------------------------------------------}

// Sessions
//-----------------------------------------------------------------------------{
tf = timeframe.period

tz = use_exchange ? syminfo.timezone : str.format('UTC{0}{1}', tz_incr >= 0 ? '+' : '-', math.abs(tz_incr))

is_sesa = math.sign(nz(time(tf, sesa_ses, tz)))
is_sesb = math.sign(nz(time(tf, sesb_ses, tz)))
is_sesc = math.sign(nz(time(tf, sesc_ses, tz)))
is_sesd = math.sign(nz(time(tf, sesd_ses, tz)))
//-----------------------------------------------------------------------------}

// Overlays - Range Only
//-----------------------------------------------------------------------------{
if show_sesa
    get_range(is_sesa, sesa_txt, sesa_css)

if show_sesb
    get_range(is_sesb, sesb_txt, sesb_css)

if show_sesc
    get_range(is_sesc, sesc_txt, sesc_css)

if show_sesd
    get_range(is_sesd, sesd_txt, sesd_css)
//-----------------------------------------------------------------------------}
// User Inputs for Customization
bullishBreakColor = input.color(color.white, "Bull CISD", inline = "bup")
bearishBreakColor = input.color(color.white, "Bear CISD", inline = "bep")

bullStr = input.string("+CISD", " ", tooltip = "Text to be displayed next to the CISD level.", inline = "bup")
bearStr = input.string("-CISD", " ", tooltip = "Text to be displayed next to the CISD level.", inline = "bep")

bullishAlerts = input.bool(false, "Alert?", "When set up through Tradingview, the script will send an alert when price closes ABOVE the current '+CISD' level.", inline = "bup")
bearishAlerts = input.bool(false, "Alert?", "When set up through Tradingview, the script will send an alert when price closes ABOVE the current '-CISD' level.", inline = "bep")

lineWidth = input.int(1, "Line Width", minval=1, maxval=5)
lookAheadBars = input.int(5, "Line Extension Bars", minval=1, maxval = 5)
styleOption = input.string("Solid (─)", title="Line Style",
     options=["Solid (─)", "Dotted (┈)", "Dashed (╌)"])
keepLevels = input.bool(false, "Keep old CISD levels")

showTable = input(true, title="Enable stat table", group = "Table")
tablePosition = input.string(defval = "Top Right", title = "Table Position", 
  options=["Top Right", "Bottom Right", "Middle Right", "Bottom Center", "Middle Left"], group = "Table")

// Structure Definitions
type MarketStructure
    float topPrice
    float bottomPrice
    bool isBullish

type cisd
    line level
    label txt
    bool completed



// Variable Declarations
var line lastTopLine = na
var line lastBottomLine = na
var MarketStructure currentStructure = MarketStructure.new(0, 0, false)

var cisdLevelsBu = array.new<cisd>()
var cisdLevelsBe = array.new<cisd>()

var bool isBullishPullback = false
var bool isBearishPullback = false

var float potentialTopPrice = na
var float potentialBottomPrice = na

var int bullishBreakIndex = na
var int bearishBreakIndex = na

var float bullishChangeLevel = na
var float bearishChangeLevel = na

var bool currentState = false

gettablePos(pos) =>
    switch pos
        "Top Right" => position.top_right
        "Bottom Right" => position.bottom_right
        "Middle Right" => position.middle_right
        "Bottom Center" => position.bottom_center
        "Middle Left" => position.bottom_left


// Pullback Detection
bearishPullbackDetected = close[1] > open[1]
bullishPullbackDetected = close[1] < open[1]

// Bearish Pullback Logic
if bearishPullbackDetected and not isBearishPullback
    isBearishPullback := true
    potentialTopPrice := open[1]
    bullishBreakIndex := bar_index[1]

// Bullish Pullback Logic
if bullishPullbackDetected and not isBullishPullback
    isBullishPullback := true
    potentialBottomPrice := open[1]
    bearishBreakIndex := bar_index[1]

// Update Potential Levels During Pullbacks
if isBullishPullback
    if open < potentialBottomPrice
        potentialBottomPrice := open
        bearishBreakIndex := bar_index
    if (close < open) and (open > potentialBottomPrice)
        potentialBottomPrice := open
        bearishBreakIndex := bar_index     

if isBearishPullback
    if open > potentialTopPrice
        potentialTopPrice := open
        bullishBreakIndex := bar_index
    if (close > open) and open < potentialTopPrice
        potentialTopPrice := open
        bullishBreakIndex := bar_index      

// Structure Updates - Bearish Break
if low < currentStructure.bottomPrice
    currentStructure.bottomPrice := low
    currentStructure.isBullish := false
    
    if isBearishPullback and (bar_index-bullishBreakIndex != 0)
        currentStructure.topPrice := math.max(high[bar_index-bullishBreakIndex],high[bar_index-bullishBreakIndex+1])
        isBearishPullback := false
        bearishLine = line.new(bullishBreakIndex, potentialTopPrice, bar_index + lookAheadBars, potentialTopPrice, color=bullishBreakColor, width=lineWidth, style = lineStyle)
        bearishLabel = label.new(bar_index + lookAheadBars, potentialTopPrice, bullStr, color=color.new(color.white,100), textcolor=bullishBreakColor, style=label.style_label_left, text_font_family = font.family_default, size = size.small, text_formatting = text.format_italic)

        b = cisd.new(bearishLine, bearishLabel, false)
        cisdLevelsBe.push(b)
    else if close[1] > open[1] and close < open
        currentStructure.topPrice := high[1]

        isBearishPullback := false
        bearishLine = line.new(bullishBreakIndex, potentialTopPrice, bar_index + lookAheadBars, potentialTopPrice, color=bearishBreakColor, width=lineWidth, style = lineStyle)
        bearishLabel = label.new(bar_index + lookAheadBars, potentialTopPrice, bullStr, color=color.new(color.white,100), textcolor=bearishBreakColor, style=label.style_label_left, text_font_family = font.family_default, size = size.small, text_formatting = text.format_italic)

        b = cisd.new(bearishLine, bearishLabel, false)
        cisdLevelsBe.push(b)

// Structure Updates - Bullish Break
if high > currentStructure.topPrice
    currentStructure.isBullish := true
    currentStructure.topPrice := high
    
    if isBullishPullback and (bar_index-bearishBreakIndex != 0)
        currentStructure.bottomPrice := math.min(low[bar_index-bearishBreakIndex],low[bar_index-bearishBreakIndex+1])
        isBullishPullback := false

        bullishLine = line.new(bearishBreakIndex, potentialBottomPrice, bar_index + lookAheadBars, potentialBottomPrice, color=bearishBreakColor, width=lineWidth, style = lineStyle)
        bullishLabel = label.new(bar_index + lookAheadBars, potentialBottomPrice, bearStr, color=color.new(color.white,100), textcolor=bearishBreakColor, style=label.style_label_left, text_font_family = font.family_default, size = size.small, text_formatting = text.format_italic)

        bu = cisd.new(bullishLine, bullishLabel, false)
        cisdLevelsBu.push(bu)
    else if close[1] < open[1] and close > open
        currentStructure.bottomPrice := low[1]

        isBullishPullback := false

        bullishLine = line.new(bearishBreakIndex, potentialBottomPrice, bar_index + lookAheadBars, potentialBottomPrice, color=bearishBreakColor, width=lineWidth, style = lineStyle)
        bullishLabel = label.new(bar_index + lookAheadBars, potentialBottomPrice, bearStr, color=color.new(color.white,100), textcolor=bearishBreakColor, style=label.style_label_left, text_font_family = font.family_default, size = size.small, text_formatting = text.format_italic)

        bu = cisd.new(bullishLine, bullishLabel, false)
        cisdLevelsBu.push(bu)


if array.size(cisdLevelsBu) > 1 and not keepLevels
    latest = array.shift(cisdLevelsBu)
    line.delete(latest.level)
    label.delete(latest.txt)

if array.size(cisdLevelsBe) > 1 and not keepLevels
    latest = array.shift(cisdLevelsBe)
    line.delete(latest.level)
    label.delete(latest.txt)

if array.size(cisdLevelsBu) >= 1
    latest = array.get(cisdLevelsBu,0)
    if not (close < latest.level.get_y2()) and not latest.completed
        line.set_x2(latest.level, bar_index+lookAheadBars)
        label.set_x(latest.txt, bar_index+lookAheadBars)
    if close < latest.level.get_y2() and not latest.completed
        latest.completed := true
        alert("Bearish CISD Formed")

        bearishLine = line.new(bullishBreakIndex, potentialTopPrice, bar_index + lookAheadBars, potentialTopPrice, color=bearishBreakColor, width=lineWidth, style = lineStyle)
        bearishLabel = label.new(bar_index + lookAheadBars, potentialTopPrice, bullStr, color=color.new(color.white,100), textcolor=bearishBreakColor, style=label.style_label_left, text_font_family = font.family_monospace, size = size.small, text_formatting = text.format_italic)

        b = cisd.new(bearishLine, bearishLabel, false)
        cisdLevelsBe.push(b)

        currentState := false


if array.size(cisdLevelsBe) >= 1 and not keepLevels
    latest = array.get(cisdLevelsBe,0)
    if not (close > latest.level.get_y2()) and not latest.completed
        line.set_x2(latest.level, bar_index+lookAheadBars)
        label.set_x(latest.txt, bar_index+lookAheadBars)
    if close > latest.level.get_y2() and not latest.completed
        latest.completed := true
        alert("Bullish CISD Formed")

        bullishLine = line.new(bearishBreakIndex, potentialBottomPrice, bar_index + lookAheadBars, potentialBottomPrice, color=bearishBreakColor, width=lineWidth, style = lineStyle)
        bullishLabel = label.new(bar_index + lookAheadBars, potentialBottomPrice, bearStr, color=color.new(color.white,100), textcolor=bearishBreakColor, style=label.style_label_left, text_font_family = font.family_monospace, size = size.small, text_formatting = text.format_italic)

        bu = cisd.new(bullishLine, bullishLabel, false)
        cisdLevelsBu.push(bu)

        currentState := true

// --- EMA BIAS for Table Display ---
var string emaBiasText = "Neutral"
if bullishBias
    emaBiasText := "Bullish"
else if bearishBias
    emaBiasText := "Bearish"
else
    emaBiasText := "Neutral"

// --- VWAP Trend Detection for Table display ---
var string vwapTrendText = "Neutral"
if close > vwapValue
    vwapTrendText := "Bullish"
else if close < vwapValue
    vwapTrendText := "Bearish"
else
    vwapTrendText := "Neutral"


if showTable and barstate.islast
    var tbl = table.new(gettablePos(tablePosition), 4, 4, bgcolor=chart.bg_color, border_color=chart.fg_color, frame_color = chart.fg_color, frame_width = 1, border_width = 1)
    table.cell(tbl, 0, 0, syminfo.ticker + ", " + timeframe.period + " neo|", text_size = size.tiny, text_color = chart.fg_color, text_font_family = font.family_monospace)
    table.cell(tbl, 0, 1, "Current State", text_color=chart.bg_color, text_size=size.small, text_font_family = font.family_monospace, text_formatting = text.format_bold, bgcolor = chart.fg_color)
    table.cell(tbl, 0, 2, currentState ? "Bullish" : "Bearish",  text_color=chart.fg_color, text_size=size.small, text_font_family = font.family_monospace, text_formatting = text.format_bold)
    table.cell(tbl, 1, 1, "EMA Bias", text_color=chart.bg_color, text_size=size.small, text_font_family = font.family_monospace, text_formatting = text.format_bold, bgcolor = chart.fg_color)
    table.cell(tbl, 1, 2, emaBiasText,  text_color=chart.fg_color, text_size=size.small, text_font_family = font.family_monospace)

    // Added VWAP Trend row
    table.cell(tbl, 2, 1, "VWAP Trend", text_color=chart.bg_color, text_size=size.small, text_font_family = font.family_monospace, text_formatting = text.format_bold, bgcolor = chart.fg_color)
    table.cell(tbl, 2, 2, vwapTrendText,  text_color=chart.fg_color, text_size=size.small, text_font_family = font.family_monospace)

///// MSS////

// Constants
Transparent_Color = color.new(color.white, 100)

// Groups
General_Settings_group = '-------MSS General Settings-------'
Timeframe_1_Group = '-------Timeframe 1 Settings--------'


// Tooltips
Hide_MS_Tooltip = 'If true will hide all MS plots such as "HH 2H" or "HH 15min"'
Hide_Breaks_Tooltip = 'If true will hide all MS breaks such as "BOS 1H" or "MSS 15min"'
Timeframe_Tooltip = 'If set to chart is true no need to alter these two inputs.'
Set_To_Chart_Tooltip = 'If set to chart is set to true, there is no need to alter the Timeframe inputs, it will automatically configure itself to the charts timeframe.'
Lower_Timeframe_Tooltip = 'If set to true and chart timeframe is higher than the choosen timeframe, structure will not display. Note plotting ltf structure on a htf will provide inaccurate plots.'
Use_High_Low_Tooltip = 'If set to true high and low values will be used to confirm market structure else if set to false close will be used.'
Display_TF_Pivots = 'If true the script will display the timeframe declared in the TF inputs'
Display_TF_MS = 'If true the script will display the timeframe\'s market structure declared in the TF inputs if Hide all Market Structure is false in general settings.'
BOS_Alert_Tooltip = 'Set to true to activate BOS alerts then proceed to set the any alert function specifically on this script.'
MSS_Alert_Tooltip = 'Set to true to activate MSS alerts then proceed to set the any alert function specifically on this script.'
BOS_Plot_Tooltip = 'If set to true the TF BOS plots will be plotted else if false they will be hidden.'
MSS_Plot_Tooltip = 'If set to true the TF MSS plots will be plotted else if false they will be hidden.'

// General Settings
Hide_All_MS = input.bool(defval = true, title = 'Hide all Market Structure', group = General_Settings_group, tooltip = Hide_MS_Tooltip)
Hide_All_Breaks = input.bool(defval = false, title = 'Hide all Structure Breaks', group = General_Settings_group, tooltip = Hide_Breaks_Tooltip)
Show_Only_On_Lower_Timeframes = input.bool(defval = true, title = 'Show Structure only on a lower Timeframe', group = General_Settings_group, tooltip = Lower_Timeframe_Tooltip)

// User Inputs
// Timeframe 1 Settings
TF_1_Use_Bos_Plot = input.bool(defval = false, title = 'Show TF 1 BOS Plots', group = Timeframe_1_Group, tooltip = BOS_Plot_Tooltip)
TF_1_Use_MSS_Plot = input.bool(defval = true, title = 'Show TF 1 MSS Plots', group = Timeframe_1_Group, tooltip = MSS_Plot_Tooltip)
TF_1_Chart_Feature = input.bool(defval = true, title = 'Set Timeframe to Chart', group = Timeframe_1_Group, tooltip = Set_To_Chart_Tooltip)
TF_1_Use_High_Low = input.bool(defval = false, title = 'Use High/Low for Bos & Mss', group = Timeframe_1_Group, tooltip = Use_High_Low_Tooltip)
TF_1_Display_Pivots = input.bool(defval = true, title = 'Display Market Structure', group = Timeframe_1_Group, tooltip = Display_TF_MS)
TF_1_Display_Timeframe = input.bool(defval = true, title = 'Display Timeframe', group = Timeframe_1_Group, tooltip = Display_TF_Pivots)
TF_1_BOS_Alert = input.bool(defval = true, title = 'Use TF 1 BOS Alert', group = Timeframe_1_Group, tooltip = BOS_Alert_Tooltip)
TF_1_MSS_Alert = input.bool(defval = true, title = 'Use TF 1 MSS Alert', group = Timeframe_1_Group, tooltip = MSS_Alert_Tooltip)
TF_1_Multip = input.int(defval = 15, minval = 1, maxval = 1440, title = 'Timeframe 1', group = Timeframe_1_Group, inline = 'T1')
TF_1_Period = input.string(defval = 'Minute', title = '', options = ['Minute', 'Hour', 'Day', 'Week', 'Month'], group = Timeframe_1_Group, inline = 'T1', tooltip = Timeframe_Tooltip)
TF_1_Swing_Length = input.int(defval = 4, title = 'Swing Length', minval = 1, group = Timeframe_1_Group)
TF_1_Line_Type = input.string(defval = 'Solid', title = 'Border Type', options = ['Solid', 'Dashed', 'Dotted'], group = Timeframe_1_Group)
TF_1_Line_Width = input.int(defval = 2, title = 'Line Width', group = Timeframe_1_Group)
TF_1_Text_Size = input.string(defval = 'Small', title = 'Text Size', options = ['Normal', 'Tiny', 'Small', 'Large', 'Huge', 'Auto'], group = Timeframe_1_Group)
TF_1_Bul_Bos_Col = input.color(defval = color.green, title = 'Bullish Bos/Mss Color', group = Timeframe_1_Group, inline = 'TF 1 Color')
TF_1_Bear_Bos_Col = input.color(defval = color.red, title = 'Bearish Bos/Mss Color', group = Timeframe_1_Group, inline = 'TF 1 Color')
TF_1_Bul_MS_Col = input.color(defval = color.white, title = 'Bullish Text MS Color', group = Timeframe_1_Group, inline = 'TF 1 Ms Color')
TF_1_Bear_MS_Col = input.color(defval = color.white, title = 'Bearish Text MS Color', group = Timeframe_1_Group, inline = 'TF 1 Ms Color')

// General functions
// Getting the line type from the user.
Line_Type_Control(Type) =>
    Line_Functionality = switch Type
        'Solid' => line.style_solid
        'Dashed' => line.style_dashed
        'Dotted' => line.style_dotted

    Line_Functionality

// Text size from the user
Text_Size_Switch(Text_Size) =>
    Text_Type = switch Text_Size
        'Normal' => size.normal
        'Tiny' => size.tiny
        'Small' => size.small
        'Large' => size.large
        'Huge' => size.huge
        'Auto' => size.auto
    Text_Type

// Timeframe functionality
// Timeframe for security functions
TF(TF_Period, TF_Multip) =>
    switch TF_Period
        'Minute' => str.tostring(TF_Multip)
        'Hour' => str.tostring(TF_Multip * 60)
        'Day' => str.tostring(TF_Multip) + 'D'
        'Week' => str.tostring(TF_Multip) + 'W'
        'Month' => str.tostring(TF_Multip) + 'M'
        => timeframe.period

// Timeframe shortcut form
TF_Display(Chart_as_Timeframe, TF_Period, TF_Multip) =>
    if Chart_as_Timeframe == false
        switch TF_Period
            'Minute' => str.tostring(TF_Multip) + 'Min'
            'Hour' => str.tostring(TF_Multip) + 'H'
            'Day' => str.tostring(TF_Multip) + 'D'
            'Week' => str.tostring(TF_Multip) + 'W'
            'Month' => str.tostring(TF_Multip) + 'M'

    else if Chart_as_Timeframe == true
        switch 
            timeframe.isminutes and timeframe.multiplier % 60 != 0 => str.tostring(timeframe.multiplier) + 'Min'

            timeframe.isminutes and timeframe.multiplier % 60 == 0 => str.tostring(timeframe.multiplier / 60) + 'H'

            timeframe.isdaily => str.tostring(timeframe.multiplier) + 'D'
            timeframe.isweekly => str.tostring(timeframe.multiplier) + 'W'
            timeframe.ismonthly => str.tostring(timeframe.multiplier) + 'M'

MTF_MS_Display(Chart_as_Timeframe, TF_Period, TF_Multip, Swing_Length) =>
    if Chart_as_Timeframe == true
        Swing_Length
    else
        switch 
            TF_Period == 'Month' and timeframe.isminutes and timeframe.multiplier % 60 == 0 and 24 * 5 * 5 / (TF_Multip * 1440 * 5 * 5 / timeframe.multiplier) * 60 == timeframe.multiplier => TF_Multip * 1440 * 5 * 5 / timeframe.multiplier * Swing_Length

            TF_Period == 'Month' and timeframe.isweekly and 5 / (TF_Multip * 1440 * 5 / timeframe.multiplier) * 1440 == timeframe.multiplier => TF_Multip * 1440 * 5 / 1440 * Swing_Length

            TF_Period == 'Month' and timeframe.isdaily and 5 * 5 / (TF_Multip * 1440 * 5 * 5 / timeframe.multiplier) * 1440 == timeframe.multiplier => TF_Multip * 1440 * 5 * 5 / 1440 * Swing_Length

            timeframe.ismonthly and timeframe.multiplier == TF_Multip and TF_Period == 'Month' => Swing_Length

            TF_Period == 'Week' and timeframe.isminutes and timeframe.multiplier % 60 == 0 and 24 * 5 / (TF_Multip * 1440 * 5 / timeframe.multiplier) * 60 == timeframe.multiplier => TF_Multip * 1440 * 5 / timeframe.multiplier * Swing_Length

            TF_Period == 'Week' and timeframe.isdaily and 5 / (TF_Multip * 1440 * 5 / timeframe.multiplier) * 1440 == timeframe.multiplier => TF_Multip * 1440 * 5 / 1440 * Swing_Length

            timeframe.isweekly and timeframe.multiplier == TF_Multip and TF_Period == 'Week' => Swing_Length

            TF_Period == 'Day' and timeframe.isminutes and timeframe.multiplier % 60 == 0 and 24 / (TF_Multip * 1440 / timeframe.multiplier) * 60 == timeframe.multiplier => TF_Multip * 1440 / timeframe.multiplier * Swing_Length

            timeframe.isdaily and timeframe.multiplier == TF_Multip and TF_Period == 'Day' => Swing_Length

            timeframe.isminutes and timeframe.multiplier % 60 != 0 and TF_Period == 'Minute' and TF_Multip == timeframe.multiplier => Swing_Length

            timeframe.isminutes and timeframe.multiplier % 60 != 0 and TF_Period == 'Minute' and TF_Multip != timeframe.multiplier => TF_Multip / 60 * 60 / timeframe.multiplier * Swing_Length

            timeframe.isminutes and timeframe.multiplier % 60 != 0 and TF_Period == 'Hour' and TF_Multip != timeframe.multiplier => TF_Multip * 60 / 60 * 60 / timeframe.multiplier * Swing_Length

            timeframe.isminutes and timeframe.multiplier % 60 != 0 and TF_Period == 'Hour' and TF_Multip == timeframe.multiplier and timeframe.multiplier * 60 == 60 => TF_Multip * 60 / 60 * 60 / timeframe.multiplier * Swing_Length

            timeframe.isminutes and timeframe.multiplier % 60 != 0 and TF_Period == 'Day' and TF_Multip != timeframe.multiplier => TF_Multip * 1440 / 60 * 60 / timeframe.multiplier * Swing_Length

            timeframe.isminutes and timeframe.multiplier % 60 == 0 and TF_Period == 'Hour' and TF_Multip * 60 == timeframe.multiplier => Swing_Length

            timeframe.isminutes and timeframe.multiplier % 60 == 0 and TF_Period == 'Hour' and TF_Multip * 60 != timeframe.multiplier => TF_Multip * 60 / timeframe.multiplier * Swing_Length

HTF_Structure_Control(Chart_as_Timeframe, TF_Period, TF_Multip) =>
    if Chart_as_Timeframe == true
        true
    else if Show_Only_On_Lower_Timeframes == false
        true
    else
        switch 
            TF_Period == 'Minute' and TF_Multip < timeframe.multiplier and timeframe.isminutes => false
            TF_Period == 'Minute' and TF_Multip >= timeframe.multiplier and timeframe.isminutes => true
            TF_Period == 'Minute' and timeframe.isdaily => false
            TF_Period == 'Minute' and timeframe.isweekly => false
            TF_Period == 'Minute' and timeframe.ismonthly => false
            TF_Period == 'Hour' and TF_Multip * 60 < timeframe.multiplier and timeframe.isminutes => false
            TF_Period == 'Hour' and TF_Multip * 60 >= timeframe.multiplier and timeframe.isminutes => true
            TF_Period == 'Hour' and timeframe.isdaily => false
            TF_Period == 'Hour' and timeframe.isweekly => false
            TF_Period == 'Hour' and timeframe.ismonthly => false
            TF_Period == 'Day' and timeframe.isdaily or timeframe.isminutes => true
            TF_Period == 'Week' and timeframe.isweekly or timeframe.isdaily or timeframe.isminutes => true
            TF_Period == 'Month' and timeframe.ismonthly or timeframe.isweekly or timeframe.isdaily or timeframe.isminutes => true

// Calculating the Mtf BOS and MSS
// Getting the high and low values
[TF_1_SH, TF_1_SL] = request.security(symbol = syminfo.tickerid, timeframe = TF_1_Chart_Feature ? timeframe.period : TF(TF_1_Period, TF_1_Multip), expression = [ta.pivothigh(high, TF_1_Swing_Length, TF_1_Swing_Length), ta.pivotlow(low, TF_1_Swing_Length, TF_1_Swing_Length)], gaps = barmerge.gaps_on)



Count_Candles_For_Structure(Direction, Condition) =>
    var int High_Count = 0
    var int Low_Count = 0

    if Direction == 'Bullish'
        for i = 0 to Condition by 1
            High_Count := i
            High_Count
        High_Count
    else if Direction == 'Bearish'
        for i = 0 to Condition by 1
            Low_Count := i
            Low_Count
        Low_Count


Market_Structure(TF_SH, TF_SL, Swing_Length, Chart_as_Timeframe, TF_Period, TF_Multip, Line_Type, Line_Width, Display_Timeframe, Display_Structure, Bul_Bos_Col, Bear_Bos_Col, Bul_Ms_Col, Bear_Ms_Col, TF_Text_Size, Use_High_Low, Use_BOS_Alert, Use_MSS_Alert, Use_Bos_Plot, Use_MSS_Plot) =>
    // Variables to identify HH, HL, LH, LL
    var float TF_Prev_High = na
    var float TF_Prev_Low = na
    TF_Prev_High_Time = 0
    TF_Prev_Low_Time = 0
    High_Count = 0
    Low_Count = 0

    //Tracking whether previous levels have been broken
    var bool TF_High_Present = false
    var bool TF_Low_Present = false

    //Tracking prev breakout
    var int Prev_Breakout_Type = 0

    //Varibales for generating BOS and CHOCH
    bool High_Broken = false
    bool Low_Broken = false
    End_High_Time = 0
    End_Low_Time = 0

    // Variables for Market Structure
    bool HH = false
    bool LH = false
    bool HL = false
    bool LL = false

    TF_High_Close_Price = request.security(symbol = syminfo.tickerid, timeframe = Chart_as_Timeframe ? timeframe.period : TF(TF_Period, TF_Multip), expression = Use_High_Low ? high : close)
    TF_Low_Close_Price = request.security(symbol = syminfo.tickerid, timeframe = Chart_as_Timeframe ? timeframe.period : TF(TF_Period, TF_Multip), expression = Use_High_Low ? low : close)

    if not na(TF_SH)
        if TF_SH >= TF_Prev_High
            HH := true
            HH
        else
            LH := true
            LH
        TF_Prev_High := TF_SH
        TF_Prev_High_Time := TF_Prev_High != TF_Prev_High[1] ? time[MTF_MS_Display(Chart_as_Timeframe, TF_Period, TF_Multip, Swing_Length)] : TF_Prev_High_Time[1]
        TF_High_Present := true
        TF_High_Present

    if not na(TF_SL)
        if TF_SL >= TF_Prev_Low
            HL := true
            HL
        else
            LL := true
            LL
        TF_Prev_Low := TF_SL
        TF_Prev_Low_Time := TF_Prev_Low != TF_Prev_Low[1] ? time[MTF_MS_Display(Chart_as_Timeframe, TF_Period, TF_Multip, Swing_Length)] : TF_Prev_Low_Time[1]
        TF_Low_Present := true
        TF_Low_Present


    if TF_High_Close_Price > TF_Prev_High and TF_High_Present
        High_Broken := true
        TF_High_Present := false
        End_High_Time := time
        End_High_Time

    if TF_Low_Close_Price < TF_Prev_Low and TF_Low_Present
        Low_Broken := true
        TF_Low_Present := false
        End_Low_Time := time
        End_Low_Time

    // Displaying Swing Levels
    if HH and Display_Timeframe and Display_Structure and not Hide_All_MS
        label.new(TF_Prev_High_Time, TF_Prev_High, 'HH \n' + TF_Display(Chart_as_Timeframe, TF_Period, TF_Multip), xloc = xloc.bar_time, color = Transparent_Color, style = label.style_label_down, textcolor = Bul_Ms_Col, size = Text_Size_Switch(TF_Text_Size))
    if HL and Display_Timeframe and Display_Structure and not Hide_All_MS
        label.new(TF_Prev_Low_Time, TF_Prev_Low, 'HL \n' + TF_Display(Chart_as_Timeframe, TF_Period, TF_Multip), xloc = xloc.bar_time, color = Transparent_Color, style = label.style_label_up, textcolor = Bul_Ms_Col, size = Text_Size_Switch(TF_Text_Size))
    if LH and Display_Timeframe and Display_Structure and not Hide_All_MS
        label.new(TF_Prev_High_Time, TF_Prev_High, 'LH \n' + TF_Display(Chart_as_Timeframe, TF_Period, TF_Multip), xloc = xloc.bar_time, color = Transparent_Color, style = label.style_label_down, textcolor = Bear_Ms_Col, size = Text_Size_Switch(TF_Text_Size))
    if LL and Display_Timeframe and Display_Structure and not Hide_All_MS
        label.new(TF_Prev_Low_Time, TF_Prev_Low, 'LL \n' + TF_Display(Chart_as_Timeframe, TF_Period, TF_Multip), xloc = xloc.bar_time, color = Transparent_Color, style = label.style_label_up, textcolor = Bear_Ms_Col, size = Text_Size_Switch(TF_Text_Size))

    High_Count := ta.barssince(HH == true or LH == true) + MTF_MS_Display(Chart_as_Timeframe, TF_Period, TF_Multip, Swing_Length)
    Low_Count := ta.barssince(HL == true or LL == true) + MTF_MS_Display(Chart_as_Timeframe, TF_Period, TF_Multip, Swing_Length)

    High_Count_Function = Count_Candles_For_Structure('Bullish', High_Count)
    Low_Count_Function = Count_Candles_For_Structure('Bearish', Low_Count)

    //Generating the BOS Lines
    if High_Broken and Display_Timeframe and not Hide_All_Breaks and HTF_Structure_Control(Chart_as_Timeframe, TF_Period, TF_Multip)
        if Prev_Breakout_Type == 1 and Use_Bos_Plot
            line.new(x1 = time[High_Count_Function], y1 = TF_Prev_High, x2 = End_High_Time, y2 = TF_Prev_High, xloc = xloc.bar_time, color = Bul_Bos_Col, style = Line_Type_Control(Line_Type), width = Line_Width)
            label.new(x = time[High_Count_Function / 2], y = TF_Prev_High, xloc = xloc.bar_time, text = 'BOS \n' + TF_Display(Chart_as_Timeframe, TF_Period, TF_Multip), color = Transparent_Color, style = label.style_label_down, textcolor = Bul_Bos_Col, size = Text_Size_Switch(TF_Text_Size))
        else if Prev_Breakout_Type == -1 and Use_MSS_Plot
            line.new(x1 = time[High_Count_Function], y1 = TF_Prev_High, x2 = End_High_Time, y2 = TF_Prev_High, xloc = xloc.bar_time, color = Bul_Bos_Col, style = Line_Type_Control(Line_Type), width = Line_Width)
            label.new(x = time[High_Count_Function / 2], y = TF_Prev_High, xloc = xloc.bar_time, text = 'MSS \n' + TF_Display(Chart_as_Timeframe, TF_Period, TF_Multip), color = Transparent_Color, style = label.style_label_down, textcolor = Bul_Bos_Col, size = Text_Size_Switch(TF_Text_Size))

        if Prev_Breakout_Type == -1 and Use_MSS_Alert
            alert(message = 'New bullish MSS formed on ' + TF_Display(Chart_as_Timeframe, TF_Period, TF_Multip), freq = alert.freq_once_per_bar_close)
        else if Prev_Breakout_Type == 1 and Use_BOS_Alert
            alert(message = 'New bullish BOS formed on ' + TF_Display(Chart_as_Timeframe, TF_Period, TF_Multip), freq = alert.freq_once_per_bar_close)

        Prev_Breakout_Type := 1
        Prev_Breakout_Type

    if Low_Broken and Display_Timeframe and not Hide_All_Breaks and HTF_Structure_Control(Chart_as_Timeframe, TF_Period, TF_Multip)
        if Prev_Breakout_Type == -1 and Use_Bos_Plot
            line.new(x1 = time[Low_Count_Function], y1 = TF_Prev_Low, x2 = End_Low_Time, y2 = TF_Prev_Low, xloc = xloc.bar_time, color = Bear_Bos_Col, style = Line_Type_Control(Line_Type), width = Line_Width)
            label.new(x = time[Low_Count_Function / 2], y = TF_Prev_Low, xloc = xloc.bar_time, text = 'BOS \n' + TF_Display(Chart_as_Timeframe, TF_Period, TF_Multip), color = Transparent_Color, textcolor = Bear_Bos_Col, style = label.style_label_up, size = Text_Size_Switch(TF_Text_Size))
        else if Prev_Breakout_Type == 1 and Use_MSS_Plot
            line.new(x1 = time[Low_Count_Function], y1 = TF_Prev_Low, x2 = End_Low_Time, y2 = TF_Prev_Low, xloc = xloc.bar_time, color = Bear_Bos_Col, style = Line_Type_Control(Line_Type), width = Line_Width)
            label.new(x = time[Low_Count_Function / 2], y = TF_Prev_Low, xloc = xloc.bar_time, text = 'MSS \n' + TF_Display(Chart_as_Timeframe, TF_Period, TF_Multip), color = Transparent_Color, textcolor = Bear_Bos_Col, style = label.style_label_up, size = Text_Size_Switch(TF_Text_Size))

        if Prev_Breakout_Type == 1 and Use_MSS_Alert
            alert(message = 'New bearish MSS formed on ' + TF_Display(Chart_as_Timeframe, TF_Period, TF_Multip), freq = alert.freq_once_per_bar_close)
        else if Prev_Breakout_Type == -1 and Use_BOS_Alert
            alert(message = 'New bearish BOS formed on ' + TF_Display(Chart_as_Timeframe, TF_Period, TF_Multip), freq = alert.freq_once_per_bar_close)

        Prev_Breakout_Type := -1
        Prev_Breakout_Type

// Calling functions
Market_Structure(TF_1_SH, TF_1_SL, TF_1_Swing_Length, TF_1_Chart_Feature, TF_1_Period, TF_1_Multip, TF_1_Line_Type, TF_1_Line_Width, TF_1_Display_Timeframe, TF_1_Display_Pivots, TF_1_Bul_Bos_Col, TF_1_Bear_Bos_Col, TF_1_Bul_MS_Col, TF_1_Bear_MS_Col, TF_1_Text_Size, TF_1_Use_High_Low, TF_1_BOS_Alert, TF_1_MSS_Alert, TF_1_Use_Bos_Plot, TF_1_Use_MSS_Plot)