1Copy the scriptPress Copy script above, or the copy button on the code below.
2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.
Source Code
442 lines of Pine Script v6 from indicators/sd-pro-v2-market-structure.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.
sd-pro-v2-market-structure.pine
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0
// https://mozilla.org/MPL/2.0/
//@version=6
indicator("Market Structure & Daily Bias [SD Pro v2]", overlay=true, max_lines_count=500, max_boxes_count=500, max_labels_count=500)
// ═══════════════════════════════════════════
// INPUTS
// ═══════════════════════════════════════════
grpStruct = "══ Market Structure ══"
swingLen = input.int(8, "Swing detection length", minval=2, maxval=20, group=grpStruct, tooltip="Bars to confirm swing. D1: 8-10, H4: 5-8, H1/M15: 3-5. Higher = cleaner, fewer labels.")
showBOS = input.bool(true, "Show BOS labels", group=grpStruct)
showCHoCH = input.bool(true, "Show CHoCH labels", group=grpStruct)
bosColor = input.color(color.new(#7F77DD, 0), "BOS color", group=grpStruct)
chochColor = input.color(color.new(#EF9F27, 0), "CHoCH color", group=grpStruct)
grpZones = "══ Supply & Demand Zones ══"
showZones = input.bool(true, "Show S/D zones", group=grpZones)
zoneLookback = input.int(50, "Zone lookback bars", minval=10, maxval=200, group=grpZones)
zoneATRMult = input.float(0.8, "Zone impulse ATR multiplier", minval=0.3, maxval=3.0, step=0.1, group=grpZones, tooltip="How strong a candle must be to form a zone. Lower = more zones. D1: 0.6-1.0, H4: 0.8-1.2, M15: 1.0-1.5")
zoneBaseATR = input.float(0.4, "Zone base ATR threshold", minval=0.1, maxval=1.0, step=0.1, group=grpZones, tooltip="Max body size of the base candle relative to ATR. Higher = allows bigger bases.")
supplyColor = input.color(color.new(#E24B4A, 80), "Supply zone color", group=grpZones)
demandColor = input.color(color.new(#1D9E75, 80), "Demand zone color", group=grpZones)
maxZones = input.int(5, "Max zones to display", minval=1, maxval=10, group=grpZones)
grpFVG = "══ Fair Value Gaps ══"
showFVG = input.bool(true, "Show FVG", group=grpFVG)
fvgBullColor = input.color(color.new(#1D9E75, 85), "Bullish FVG color", group=grpFVG)
fvgBearColor = input.color(color.new(#E24B4A, 85), "Bearish FVG color", group=grpFVG)
fvgMitigation = input.bool(true, "Remove mitigated FVGs", group=grpFVG, tooltip="Delete FVG boxes when price fills them.")
grpBias = "══ Daily Bias Panel ══"
showPanel = input.bool(true, "Show bias panel", group=grpBias)
panelPos = input.string("Top Right", "Panel position", options=["Top Right", "Top Left", "Bottom Right", "Bottom Left"], group=grpBias)
panelSize = input.string("Small", "Panel size", options=["Tiny", "Small", "Normal", "Large"], group=grpBias, tooltip="Dashboard text and cell size.")
htfTF = input.timeframe("D", "HTF for bias", group=grpBias)
grpSession = "══ Session Lines ══"
showSessions = input.bool(true, "Show session levels", group=grpSession)
showPrevDayHL = input.bool(true, "Previous day high/low (auto-off on D1+)", group=grpSession, tooltip="Automatically disabled on Daily and higher timeframes where PDH/PDL creates clutter.")
// ═══════════════════════════════════════════
// PANEL SIZE HELPER
// ═══════════════════════════════════════════
panelSizeTitle = switch panelSize
"Tiny" => size.tiny
"Small" => size.small
"Normal" => size.normal
"Large" => size.large
=> size.small
panelSizeBody = switch panelSize
"Tiny" => size.tiny
"Small" => size.tiny
"Normal" => size.small
"Large" => size.normal
=> size.tiny
// ═══════════════════════════════════════════
// SWING DETECTION
// ═══════════════════════════════════════════
var float swingHighPrice = na
var int swingHighBar = na
var float swingLowPrice = na
var int swingLowBar = na
var float prevSwingHigh = na
var int prevSwingHighBar = na
var float prevSwingLow = na
var int prevSwingLowBar = na
ph = ta.pivothigh(high, swingLen, swingLen)
pl = ta.pivotlow(low, swingLen, swingLen)
if not na(ph)
prevSwingHigh := swingHighPrice
prevSwingHighBar := swingHighBar
swingHighPrice := ph
swingHighBar := bar_index - swingLen
if not na(pl)
prevSwingLow := swingLowPrice
prevSwingLowBar := swingLowBar
swingLowPrice := pl
swingLowBar := bar_index - swingLen
// ═══════════════════════════════════════════
// MARKET STRUCTURE (BOS / CHoCH) — FIXED
// ═══════════════════════════════════════════
var int trend = 0
var float lastBullHigh = na
var float lastBullLow = na
var float lastBearHigh = na
var float lastBearLow = na
var float brokenBullLevel = na
var float brokenBearLevel = na
var int structureShift = 0
structureShift := 0
if trend == 1 and not na(swingHighPrice) and close > swingHighPrice
if (close > lastBullHigh or na(lastBullHigh)) and swingHighPrice != brokenBullLevel
structureShift := 1
lastBullHigh := swingHighPrice
lastBullLow := swingLowPrice
brokenBullLevel := swingHighPrice
if trend == -1 and not na(swingLowPrice) and close < swingLowPrice
if (close < lastBearLow or na(lastBearLow)) and swingLowPrice != brokenBearLevel
structureShift := -1
lastBearLow := swingLowPrice
lastBearHigh := swingHighPrice
brokenBearLevel := swingLowPrice
if trend == -1 and not na(lastBearHigh) and close > lastBearHigh
structureShift := 2
trend := 1
lastBullHigh := lastBearHigh
lastBullLow := lastBearLow
lastBearHigh := na
lastBearLow := na
brokenBullLevel := lastBullHigh
brokenBearLevel := na
if trend == 1 and not na(lastBullLow) and close < lastBullLow
structureShift := -2
trend := -1
lastBearHigh := lastBullHigh
lastBearLow := lastBullLow
lastBullHigh := na
lastBullLow := na
brokenBearLevel := lastBearLow
brokenBullLevel := na
if trend == 0
if not na(swingHighPrice) and not na(prevSwingHigh)
if swingHighPrice > prevSwingHigh and swingLowPrice > prevSwingLow
trend := 1
lastBullHigh := swingHighPrice
lastBullLow := swingLowPrice
else if swingHighPrice < prevSwingHigh and swingLowPrice < prevSwingLow
trend := -1
lastBearHigh := swingHighPrice
lastBearLow := swingLowPrice
if structureShift == 1 and showBOS
label.new(bar_index, high, "BOS", color=color.new(color.white, 100), textcolor=bosColor, style=label.style_label_down, size=size.tiny)
line.new(bar_index - 5, swingHighPrice, bar_index, swingHighPrice, color=bosColor, style=line.style_dashed, width=1)
if structureShift == -1 and showBOS
label.new(bar_index, low, "BOS", color=color.new(color.white, 100), textcolor=bosColor, style=label.style_label_up, size=size.tiny)
line.new(bar_index - 5, swingLowPrice, bar_index, swingLowPrice, color=bosColor, style=line.style_dashed, width=1)
if structureShift == 2 and showCHoCH
label.new(bar_index, high, "CHoCH", color=color.new(color.white, 100), textcolor=chochColor, style=label.style_label_down, size=size.tiny)
line.new(bar_index - 5, lastBullHigh, bar_index, lastBullHigh, color=chochColor, style=line.style_dashed, width=2)
if structureShift == -2 and showCHoCH
label.new(bar_index, low, "CHoCH", color=color.new(color.white, 100), textcolor=chochColor, style=label.style_label_up, size=size.tiny)
line.new(bar_index - 5, lastBearLow, bar_index, lastBearLow, color=chochColor, style=line.style_dashed, width=2)
// ═══════════════════════════════════════════
// SUPPLY & DEMAND ZONES
// ═══════════════════════════════════════════
var array<box> supplyBoxes = array.new<box>()
var array<box> demandBoxes = array.new<box>()
bullImpulse = close > open and (close - open) > zoneATRMult * ta.atr(14) and close > high[1]
bearBase = close[1] < open[1] or (math.abs(close[1] - open[1]) < zoneBaseATR * ta.atr(14))
if showZones and bullImpulse and bearBase
zoneTop = math.max(open[1], close[1])
zoneBottom = low[1]
if zoneTop > zoneBottom
newBox = box.new(bar_index - 1, zoneTop, bar_index + 50, zoneBottom, border_color=color.new(#1D9E75, 60), bgcolor=demandColor, border_width=1)
array.push(demandBoxes, newBox)
if array.size(demandBoxes) > maxZones
oldBox = array.shift(demandBoxes)
box.delete(oldBox)
bearImpulse = close < open and (open - close) > zoneATRMult * ta.atr(14) and close < low[1]
bullBase = close[1] > open[1] or (math.abs(close[1] - open[1]) < zoneBaseATR * ta.atr(14))
if showZones and bearImpulse and bullBase
zoneTop = high[1]
zoneBottom = math.min(open[1], close[1])
if zoneTop > zoneBottom
newBox = box.new(bar_index - 1, zoneTop, bar_index + 50, zoneBottom, border_color=color.new(#E24B4A, 60), bgcolor=supplyColor, border_width=1)
array.push(supplyBoxes, newBox)
if array.size(supplyBoxes) > maxZones
oldBox = array.shift(supplyBoxes)
box.delete(oldBox)
if array.size(demandBoxes) > 0
for i = array.size(demandBoxes) - 1 to 0
b = array.get(demandBoxes, i)
zTop = box.get_top(b)
zBot = box.get_bottom(b)
if close < zBot
box.delete(b)
array.remove(demandBoxes, i)
else
box.set_right(b, bar_index + 20)
if array.size(supplyBoxes) > 0
for i = array.size(supplyBoxes) - 1 to 0
b = array.get(supplyBoxes, i)
zTop = box.get_top(b)
zBot = box.get_bottom(b)
if close > zTop
box.delete(b)
array.remove(supplyBoxes, i)
else
box.set_right(b, bar_index + 20)
// ═══════════════════════════════════════════
// FAIR VALUE GAPS (FVG)
// ═══════════════════════════════════════════
var array<box> fvgBullBoxes = array.new<box>()
var array<box> fvgBearBoxes = array.new<box>()
bullFVG = low > high[2] and close[1] > open[1]
bearFVG = high < low[2] and close[1] < open[1]
if showFVG and bullFVG
newFVG = box.new(bar_index - 1, low, bar_index + 10, high[2], border_color=color.new(#1D9E75, 70), bgcolor=fvgBullColor, border_width=0)
array.push(fvgBullBoxes, newFVG)
if showFVG and bearFVG
newFVG = box.new(bar_index - 1, low[2], bar_index + 10, high, border_color=color.new(#E24B4A, 70), bgcolor=fvgBearColor, border_width=0)
array.push(fvgBearBoxes, newFVG)
if fvgMitigation
if array.size(fvgBullBoxes) > 0
for i = array.size(fvgBullBoxes) - 1 to 0
b = array.get(fvgBullBoxes, i)
if close < box.get_bottom(b)
box.delete(b)
array.remove(fvgBullBoxes, i)
else
box.set_right(b, bar_index + 5)
if array.size(fvgBearBoxes) > 0
for i = array.size(fvgBearBoxes) - 1 to 0
b = array.get(fvgBearBoxes, i)
if close > box.get_top(b)
box.delete(b)
array.remove(fvgBearBoxes, i)
else
box.set_right(b, bar_index + 5)
// ═══════════════════════════════════════════
// HTF BIAS CALCULATION
// ═══════════════════════════════════════════
htfHigh = request.security(syminfo.tickerid, htfTF, high, lookahead=barmerge.lookahead_off)
htfLow = request.security(syminfo.tickerid, htfTF, low, lookahead=barmerge.lookahead_off)
htfClose = request.security(syminfo.tickerid, htfTF, close, lookahead=barmerge.lookahead_off)
htfOpen = request.security(syminfo.tickerid, htfTF, open, lookahead=barmerge.lookahead_off)
htfHigh1 = request.security(syminfo.tickerid, htfTF, high[1], lookahead=barmerge.lookahead_off)
htfLow1 = request.security(syminfo.tickerid, htfTF, low[1], lookahead=barmerge.lookahead_off)
htfClose1 = request.security(syminfo.tickerid, htfTF, close[1], lookahead=barmerge.lookahead_off)
htfHigh2 = request.security(syminfo.tickerid, htfTF, high[2], lookahead=barmerge.lookahead_off)
htfLow2 = request.security(syminfo.tickerid, htfTF, low[2], lookahead=barmerge.lookahead_off)
htfClose2 = request.security(syminfo.tickerid, htfTF, close[2], lookahead=barmerge.lookahead_off)
htfHigh3 = request.security(syminfo.tickerid, htfTF, high[3], lookahead=barmerge.lookahead_off)
htfLow3 = request.security(syminfo.tickerid, htfTF, low[3], lookahead=barmerge.lookahead_off)
htfHigh4 = request.security(syminfo.tickerid, htfTF, high[4], lookahead=barmerge.lookahead_off)
htfLow4 = request.security(syminfo.tickerid, htfTF, low[4], lookahead=barmerge.lookahead_off)
htf5High = math.max(htfHigh1, math.max(htfHigh2, math.max(htfHigh3, htfHigh4)))
htf5Low = math.min(htfLow1, math.min(htfLow2, math.min(htfLow3, htfLow4)))
htfHH_1 = htfHigh1 > htfHigh2
htfHL_1 = htfLow1 > htfLow2
htfHH_2 = htfHigh2 > htfHigh3
htfHL_2 = htfLow2 > htfLow3
htfLH_1 = htfHigh1 < htfHigh2
htfLL_1 = htfLow1 < htfLow2
htfLH_2 = htfHigh2 < htfHigh3
htfLL_2 = htfLow2 < htfLow3
htfBullish = (htfHH_1 and htfHL_1) or (htfHH_2 and htfHL_2)
htfBearish = (htfLH_1 and htfLL_1) or (htfLH_2 and htfLL_2)
if htfBullish and htfBearish
htfBullish := false
htfBearish := false
currentBull = trend == 1
currentBear = trend == -1
var string dailyBias = "Neutral"
if htfBullish and currentBull
dailyBias := "Strong Bullish"
else if htfBullish and currentBear
dailyBias := "Bullish (conflict)"
else if htfBearish and currentBear
dailyBias := "Strong Bearish"
else if htfBearish and currentBull
dailyBias := "Bearish (conflict)"
else if htfBullish
dailyBias := "Bullish"
else if htfBearish
dailyBias := "Bearish"
else
dailyBias := "Neutral / Ranging"
var string ctfStructure = "Undefined"
if trend == 1
ctfStructure := "Bullish (HH/HL)"
else if trend == -1
ctfStructure := "Bearish (LH/LL)"
else
ctfStructure := "Undefined"
var string lastEvent = "None"
var int lastEventBar = 0
if structureShift == 1
lastEvent := "Bullish BOS"
lastEventBar := bar_index
else if structureShift == -1
lastEvent := "Bearish BOS"
lastEventBar := bar_index
else if structureShift == 2
lastEvent := "Bullish CHoCH"
lastEventBar := bar_index
else if structureShift == -2
lastEvent := "Bearish CHoCH"
lastEventBar := bar_index
eventAge = bar_index - lastEventBar
lastEventDisp = lastEvent + (eventAge > 100 and lastEvent != "None" ? " (" + str.tostring(eventAge) + " bars ago)" : "")
// ═══════════════════════════════════════════
// PREVIOUS DAY HIGH / LOW
// ═══════════════════════════════════════════
prevDayHigh = request.security(syminfo.tickerid, "D", high[1], lookahead=barmerge.lookahead_on)
prevDayLow = request.security(syminfo.tickerid, "D", low[1], lookahead=barmerge.lookahead_on)
isIntraday = timeframe.isintraday
if showSessions and showPrevDayHL and isIntraday
if ta.change(time("D")) != 0
line.new(bar_index, prevDayHigh, bar_index + 30, prevDayHigh, color=color.new(#E24B4A, 50), style=line.style_dotted, width=1)
label.new(bar_index + 30, prevDayHigh, "PDH", color=color.new(color.white, 100), textcolor=color.new(#E24B4A, 30), style=label.style_label_left, size=size.tiny)
line.new(bar_index, prevDayLow, bar_index + 30, prevDayLow, color=color.new(#1D9E75, 50), style=line.style_dotted, width=1)
label.new(bar_index + 30, prevDayLow, "PDL", color=color.new(color.white, 100), textcolor=color.new(#1D9E75, 30), style=label.style_label_left, size=size.tiny)
// ═══════════════════════════════════════════
// BIAS DASHBOARD PANEL
// ═══════════════════════════════════════════
if showPanel and barstate.islast
biasClr = switch dailyBias
"Strong Bullish" => color.new(#1D9E75, 0)
"Bullish" => color.new(#1D9E75, 30)
"Bullish (conflict)" => color.new(#EF9F27, 0)
"Strong Bearish" => color.new(#E24B4A, 0)
"Bearish" => color.new(#E24B4A, 30)
"Bearish (conflict)" => color.new(#EF9F27, 0)
=> color.gray
trendClr = trend == 1 ? color.new(#1D9E75, 0) : trend == -1 ? color.new(#E24B4A, 0) : color.gray
var table panel = table.new(
panelPos == "Top Right" ? position.top_right :
panelPos == "Top Left" ? position.top_left :
panelPos == "Bottom Right" ? position.bottom_right :
position.bottom_left,
2, 10,
bgcolor=color.new(#1a1a2e, 0),
border_color=color.new(color.gray, 70),
border_width=1,
frame_color=color.new(color.gray, 70),
frame_width=1)
table.cell(panel, 0, 0, "SD PRO v2 — STRUCTURE & BIAS", text_color=color.white, text_size=panelSizeTitle, text_halign=text.align_left)
table.merge_cells(panel, 0, 0, 1, 0)
table.cell(panel, 0, 1, "Timeframe", text_color=color.gray, text_size=panelSizeBody, text_halign=text.align_left)
table.cell(panel, 1, 1, timeframe.period, text_color=color.white, text_size=panelSizeTitle, text_halign=text.align_right)
table.cell(panel, 0, 2, "Daily Bias", text_color=color.gray, text_size=panelSizeBody, text_halign=text.align_left)
table.cell(panel, 1, 2, dailyBias, text_color=biasClr, text_size=panelSizeTitle, text_halign=text.align_right)
table.cell(panel, 0, 3, "HTF Structure", text_color=color.gray, text_size=panelSizeBody, text_halign=text.align_left)
htfStr = htfBullish ? "Bullish" : htfBearish ? "Bearish" : "Ranging"
htfStrClr = htfBullish ? color.new(#1D9E75, 0) : htfBearish ? color.new(#E24B4A, 0) : color.gray
table.cell(panel, 1, 3, htfStr, text_color=htfStrClr, text_size=panelSizeTitle, text_halign=text.align_right)
table.cell(panel, 0, 4, "CTF Structure", text_color=color.gray, text_size=panelSizeBody, text_halign=text.align_left)
table.cell(panel, 1, 4, ctfStructure, text_color=trendClr, text_size=panelSizeTitle, text_halign=text.align_right)
table.cell(panel, 0, 5, "Last Event", text_color=color.gray, text_size=panelSizeBody, text_halign=text.align_left)
evtClr = structureShift == 1 or structureShift == 2 ? color.new(#1D9E75, 0) : structureShift == -1 or structureShift == -2 ? color.new(#E24B4A, 0) : color.gray
table.cell(panel, 1, 5, lastEventDisp, text_color=evtClr, text_size=panelSizeTitle, text_halign=text.align_right)
table.cell(panel, 0, 6, "Swing High", text_color=color.gray, text_size=panelSizeBody, text_halign=text.align_left)
table.cell(panel, 1, 6, not na(swingHighPrice) ? str.tostring(swingHighPrice, format.mintick) : "—", text_color=color.new(#E24B4A, 20), text_size=panelSizeTitle, text_halign=text.align_right)
table.cell(panel, 0, 7, "Swing Low", text_color=color.gray, text_size=panelSizeBody, text_halign=text.align_left)
table.cell(panel, 1, 7, not na(swingLowPrice) ? str.tostring(swingLowPrice, format.mintick) : "—", text_color=color.new(#1D9E75, 20), text_size=panelSizeTitle, text_halign=text.align_right)
table.cell(panel, 0, 8, "Active Zones", text_color=color.gray, text_size=panelSizeBody, text_halign=text.align_left)
zoneCount = str.tostring(array.size(supplyBoxes)) + "S / " + str.tostring(array.size(demandBoxes)) + "D"
table.cell(panel, 1, 8, zoneCount, text_color=color.white, text_size=panelSizeTitle, text_halign=text.align_right)
table.cell(panel, 0, 9, "Active FVGs", text_color=color.gray, text_size=panelSizeBody, text_halign=text.align_left)
fvgCount = str.tostring(array.size(fvgBullBoxes)) + "Bull / " + str.tostring(array.size(fvgBearBoxes)) + "Bear"
table.cell(panel, 1, 9, fvgCount, text_color=color.white, text_size=panelSizeTitle, text_halign=text.align_right)
// ═══════════════════════════════════════════
// BACKGROUND COLOR FOR BIAS
// ═══════════════════════════════════════════
bgClr = trend == 1 ? color.new(#1D9E75, 95) : trend == -1 ? color.new(#E24B4A, 95) : na
bgcolor(bgClr, title="Structure bias background")
// ═══════════════════════════════════════════
// ALERTS
// ═══════════════════════════════════════════
alertcondition(structureShift == 1, "Bullish BOS", "Bullish BOS detected")
alertcondition(structureShift == -1, "Bearish BOS", "Bearish BOS detected")
alertcondition(structureShift == 2, "Bullish CHoCH", "Bullish CHoCH — potential reversal to upside")
alertcondition(structureShift == -2, "Bearish CHoCH", "Bearish CHoCH — potential reversal to downside")
alertcondition(bullFVG, "Bullish FVG", "Bullish Fair Value Gap detected")
alertcondition(bearFVG, "Bearish FVG", "Bearish Fair Value Gap detected")
Overview
Market Structure & Daily Bias SD Pro v2 calculates Break of Structure (BOS) and Change of Character (CHoCH) using pivot swing detection, auto-draws Supply and Demand zones based on ATR momentum, and plots Fair Value Gaps with mitigation removal. It also draws Previous Day High and Low session levels and displays a higher-timeframe bias panel directly on the main price chart.
Pivot-based BOS and CHoCH market structure labels
Automated ATR-filtered Supply and Demand zones
Fair Value Gap boxes with mitigation removal option
The inputs you can change from the gear icon on the chart. Defaults are the author's.
Setting
Type
Default
Variable
Swing detection length
int
8
swingLen
Show BOS labels
bool
true
showBOS
Show CHoCH labels
bool
true
showCHoCH
BOS color
color
color.new(#7F77DD, 0)
bosColor
CHoCH color
color
color.new(#EF9F27, 0)
chochColor
Show S/D zones
bool
true
showZones
Zone lookback bars
int
50
zoneLookback
Zone impulse ATR multiplier
float
0.8
zoneATRMult
Zone base ATR threshold
float
0.4
zoneBaseATR
Supply zone color
color
color.new(#E24B4A, 80)
supplyColor
Demand zone color
color
color.new(#1D9E75, 80)
demandColor
Max zones to display
int
5
maxZones
Show all 22 settings
Setting
Type
Default
Variable
Show FVG
bool
true
showFVG
Bullish FVG color
color
color.new(#1D9E75, 85)
fvgBullColor
Bearish FVG color
color
color.new(#E24B4A, 85)
fvgBearColor
Remove mitigated FVGs
bool
true
fvgMitigation
Show bias panel
bool
true
showPanel
Panel position
string
Top Right
panelPos
Panel size
string
Small
panelSize
HTF for bias
timeframe
D
htfTF
Show session levels
bool
true
showSessions
Previous day high/low (auto-off on D1+)
bool
true
showPrevDayHL
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.
This overlay indicator scans a pasted list of symbols for ICT liquidity sweep patterns using prior swing sweeps. The screening method looks back one, two, or three swings and can list long and short signals in a results table with adjustable rows, position, an
The Golden Bullet Strategy is an overlay signal indicator based on Smart Money Concepts and time-based liquidity models. It identifies liquidity sweeps of a designated reference session range during a specified hunt window. It then confirms Market Structure Sh
Indicatorv6SMC / ICT / price actionSessions & time
This indicator identifies fractal-based pivot highs and lows to map out market structure directly on the price chart. It detects bullish and bearish structure breaks, automatically labeling Break of Structure (BOS) and Change of Character (ChoCH) events when p
Apex Trend & Liquidity Master calculates a trend cloud using customizable moving averages expanded by a volatility multiplier directly on the main price chart. It identifies dynamic support and resistance liquidity zones from swing high and low pivots, extendi
The CISD with Fib/Range Extensions and Stats indicator tracks Change in State of Delivery (CISD) level breakouts on the price chart. It detects pullback structures filtered by ATR and volume conditions, then projects future target levels using customizable Fib
MTF State of Delivery tracks lower timeframe and higher timeframe orderflow delivery states by identifying bullish and bearish delivery levels across timeframes. It plots confirmed and pending orderflow lines directly on the price chart and provides an optiona