// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.
0
at [Link]
// Join our channel for more free tools: [Link]
plot(close)
//@version=6
indicator("ICT Structure Levels (ST/IT/LT)", overlay=true, max_labels_count=200)
// ========================= Inputs =========================
showST = [Link](true, "Show STH/STL", group="Short-Term (ST)")
showIT = [Link](true, "Show ITH/ITL", group="Intermediary (IT)")
showDebug = [Link](true, "Show debug info", group="Debug")
// ========================= Colors =========================
colSTH = [Link]
colSTL = [Link]
colITH = [Link]
colITL = [Link]
// ========================= Helpers =========================
fmtPrice(p) => [Link](p, [Link])
// Wick detection functions
hasUpperWick(off) => high[off] > [Link](open[off], close[off])
hasLowerWick(off) => low[off] < [Link](open[off], close[off])
// ========================= EXACT 3-Candle Detection WITH WICK REQUIREMENTS
=========================
// STL: 3 candles - middle lowest + sides higher + sides must have lower wicks
detect_STL_exact() =>
if bar_index < 2
[false, 0.0, 0]
else
// Get the 3 consecutive candles
left_candle_low = low[2] // Candle 1 (older)
middle_candle_low = low[1] // Candle 2 (middle) - must be lowest
right_candle_low = low[0] // Candle 3 (newer)
// Basic formation: middle must be strictly lower than both sides
valid_formation = middle_candle_low < left_candle_low and middle_candle_low
< right_candle_low
// Wick requirement: both side candles must have lower wicks
valid_wicks = hasLowerWick(2) and hasLowerWick(0)
// Both conditions must be true
is_valid_stl = valid_formation and valid_wicks
[is_valid_stl, middle_candle_low, bar_index - 1]
// STH: 3 candles - middle highest + sides lower + sides must have upper wicks
detect_STH_exact() =>
if bar_index < 2
[false, 0.0, 0]
else
// Get the 3 consecutive candles
left_candle_high = high[2] // Candle 1 (older)
middle_candle_high = high[1] // Candle 2 (middle) - must be highest
right_candle_high = high[0] // Candle 3 (newer)
// Basic formation: middle must be strictly higher than both sides
valid_formation = middle_candle_high > left_candle_high and
middle_candle_high > right_candle_high
// Wick requirement: both side candles must have upper wicks
valid_wicks = hasUpperWick(2) and hasUpperWick(0)
// Both conditions must be true
is_valid_sth = valid_formation and valid_wicks
[is_valid_sth, middle_candle_high, bar_index - 1]
// ========================= Store Valid ST Structures =========================
var array<float> valid_stl_prices = [Link]<float>()
var array<int> valid_stl_bars = [Link]<int>()
var array<float> valid_sth_prices = [Link]<float>()
var array<int> valid_sth_bars = [Link]<int>()
[is_stl, stl_price, stl_bar] = detect_STL_exact()
[is_sth, sth_price, sth_bar] = detect_STH_exact()
// Store only when detected
if is_stl
[Link](valid_stl_prices, stl_price)
[Link](valid_stl_bars, stl_bar)
if [Link](valid_stl_prices) > 50
[Link](valid_stl_prices)
[Link](valid_stl_bars)
if is_sth
[Link](valid_sth_prices, sth_price)
[Link](valid_sth_bars, sth_bar)
if [Link](valid_sth_prices) > 50
[Link](valid_sth_prices)
[Link](valid_sth_bars)
// ========================= EXACT IT Detection =========================
// ITL: STL between two other CONFIRMED STL where left and right are HIGHER than
middle
detect_ITL_exact() =>
if [Link](valid_stl_prices) < 3
[false, 0.0, 0]
else
size = [Link](valid_stl_prices)
// Check recent STL formations for ITL pattern - be more selective
for i = size - 2 to [Link](size - 3, 1) // Only check very recent
middle_stl_price = [Link](valid_stl_prices, i)
middle_stl_bar = [Link](valid_stl_bars, i)
// Find CONFIRMED STL to the LEFT (older than middle)
left_stl_price = float(na)
left_stl_found = false
for j = i - 1 to [Link](i - 10, 0) // Look within reasonable range
candidate_bar = [Link](valid_stl_bars, j)
if candidate_bar < middle_stl_bar
left_stl_price := [Link](valid_stl_prices, j)
left_stl_found := true
break
// Find CONFIRMED STL to the RIGHT (newer than middle)
right_stl_price = float(na)
right_stl_found = false
for k = i + 1 to [Link](i + 10, size - 1) // Look within reasonable
range
candidate_bar = [Link](valid_stl_bars, k)
if candidate_bar > middle_stl_bar
right_stl_price := [Link](valid_stl_prices, k)
right_stl_found := true
break
// ITL rule: BOTH side STLs must exist AND be HIGHER than middle STL
if left_stl_found and right_stl_found and not na(left_stl_price) and
not na(right_stl_price)
if left_stl_price > middle_stl_price and right_stl_price >
middle_stl_price
[true, middle_stl_price, middle_stl_bar]
else
[false, 0.0, 0]
else
[false, 0.0, 0]
// ITH: STH between two other CONFIRMED STH where left and right are LOWER than
middle
detect_ITH_exact() =>
if [Link](valid_sth_prices) < 3
[false, 0.0, 0]
else
size = [Link](valid_sth_prices)
// Check recent STH formations for ITH pattern - be more selective
for i = size - 2 to [Link](size - 3, 1) // Only check very recent
middle_sth_price = [Link](valid_sth_prices, i)
middle_sth_bar = [Link](valid_sth_bars, i)
// Find CONFIRMED STH to the LEFT (older than middle)
left_sth_price = float(na)
left_sth_found = false
for j = i - 1 to [Link](i - 10, 0) // Look within reasonable range
candidate_bar = [Link](valid_sth_bars, j)
if candidate_bar < middle_sth_bar
left_sth_price := [Link](valid_sth_prices, j)
left_sth_found := true
break
// Find CONFIRMED STH to the RIGHT (newer than middle)
right_sth_price = float(na)
right_sth_found = false
for k = i + 1 to [Link](i + 10, size - 1) // Look within reasonable
range
candidate_bar = [Link](valid_sth_bars, k)
if candidate_bar > middle_sth_bar
right_sth_price := [Link](valid_sth_prices, k)
right_sth_found := true
break
// ITH rule: BOTH side STHs must exist AND be LOWER than middle STH
if left_sth_found and right_sth_found and not na(left_sth_price) and
not na(right_sth_price)
if left_sth_price < middle_sth_price and right_sth_price <
middle_sth_price
[true, middle_sth_price, middle_sth_bar]
else
[false, 0.0, 0]
else
[false, 0.0, 0]
[is_itl, itl_price, itl_bar] = detect_ITL_exact()
[is_ith, ith_price, ith_bar] = detect_ITH_exact()
// ========================= Selective Visualization =========================
// Only show ST structures occasionally to reduce clutter - every 5th detection
var int stl_display_counter = 0
var int sth_display_counter = 0
if showST and is_stl
stl_display_counter := stl_display_counter + 1
if stl_display_counter % 3 == 0 // Show every 3rd STL
[Link](stl_bar, stl_price, text="STL", xloc=xloc.bar_index,
style=label.style_label_up,
color=[Link](colSTL, 15), textcolor=[Link],
size=[Link],
tooltip="STL: " + fmtPrice(stl_price))
if showST and is_sth
sth_display_counter := sth_display_counter + 1
if sth_display_counter % 3 == 0 // Show every 3rd STH
[Link](sth_bar, sth_price, text="STH", xloc=xloc.bar_index,
style=label.style_label_down,
color=[Link](colSTH, 15), textcolor=[Link],
size=[Link],
tooltip="STH: " + fmtPrice(sth_price))
// Always show IT structures when found
if showIT and is_itl
lineEndX = itl_bar + 8
lineEndY = itl_price
[Link](x1=itl_bar, y1=itl_price, x2=lineEndX, y2=lineEndY,
xloc=xloc.bar_index, extend=[Link],
color=[Link](colITL, 0), width=1)
[Link](itl_bar, itl_price, text="●", xloc=xloc.bar_index,
style=label.style_none,
color=[Link]([Link], 100), textcolor=colITL, size=[Link])
[Link](lineEndX, lineEndY, text="ITL", xloc=xloc.bar_index,
style=label.style_label_left,
color=[Link](colITL, 15), textcolor=[Link], size=[Link],
tooltip="ITL: " + fmtPrice(itl_price))
if showIT and is_ith
lineEndX = ith_bar + 8
lineEndY = ith_price
[Link](x1=ith_bar, y1=ith_price, x2=lineEndX, y2=lineEndY,
xloc=xloc.bar_index, extend=[Link],
color=[Link](colITH, 0), width=1)
[Link](ith_bar, ith_price, text="●", xloc=xloc.bar_index,
style=label.style_none,
color=[Link]([Link], 100), textcolor=colITH, size=[Link])
[Link](lineEndX, lineEndY, text="ITH", xloc=xloc.bar_index,
style=label.style_label_left,
color=[Link](colITH, 15), textcolor=[Link], size=[Link],
tooltip="ITH: " + fmtPrice(ith_price))
// ========================= Debug Info =========================
var int stl_total = 0
var int sth_total = 0
var int itl_total = 0
var int ith_total = 0
if is_stl
stl_total := stl_total + 1
if is_sth
sth_total := sth_total + 1
if is_itl
itl_total := itl_total + 1
if is_ith
ith_total := ith_total + 1
if [Link] and showDebug
var table debugTable = [Link](position.top_right, 3, 4, bgcolor=[Link],
border_width=1)
[Link](debugTable, 0, 0, "", bgcolor=[Link])
[Link](debugTable, 1, 0, "ST", bgcolor=[Link], text_color=[Link],
text_size=[Link])
[Link](debugTable, 2, 0, "IT", bgcolor=[Link], text_color=[Link],
text_size=[Link])
[Link](debugTable, 0, 1, "H", bgcolor=[Link], text_color=[Link],
text_size=[Link])
[Link](debugTable, 1, 1, [Link](sth_total), text_color=[Link],
text_size=[Link])
[Link](debugTable, 2, 1, [Link](ith_total), text_color=[Link],
text_size=[Link])
[Link](debugTable, 0, 2, "L", bgcolor=[Link], text_color=[Link],
text_size=[Link])
[Link](debugTable, 1, 2, [Link](stl_total), text_color=[Link],
text_size=[Link])
[Link](debugTable, 2, 2, [Link](itl_total), text_color=[Link],
text_size=[Link])
// Arrays info
[Link](debugTable, 0, 3, "Stored", bgcolor=[Link],
text_color=[Link], text_size=[Link])
[Link](debugTable, 1, 3, [Link]([Link](valid_stl_prices)) + "/" +
[Link]([Link](valid_sth_prices)), text_color=[Link],
text_size=[Link])
[Link](debugTable, 2, 3, "Exact", text_color=[Link],
text_size=[Link])
//
===================================================================================
=======
// === Dashboard with Telegram Link ===
var table myTable = [Link](position.top_center, 1, 1, border_width=1,
frame_color=[Link], bgcolor=[Link])
// Add Telegram Message to Dashboard
[Link](myTable, 0, 0, "Join Telegram @simpleforextools", bgcolor=[Link],
text_color=[Link], text_size=[Link])