USER
//@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)
bearishBias = (emaValue < emaValue2) and (emaValue2 < 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 := "Only Buy"
else if bearishBias
emaBiasText := "Only Sell"
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)