OPEN-SOURCE SCRIPT
Liquidity & SMT Detector

//version=5
indicator("Liquidity & SMT Detector", overlay=true, max_lines_count=500, max_labels_count=500)
// ============================================
// INPUT SETTINGS
// ============================================
// Group 1: Liquidity Detection
swing_length = input.int(10, "Swing Length", minval=3, maxval=50, group="Liquidity Detection")
line_color_high = input.color(color.red, "High Line Color", group="Liquidity Detection")
line_color_low = input.color(color.green, "Low Line Color", group="Liquidity Detection")
line_width = input.int(2, "Line Width", minval=1, maxval=5, group="Liquidity Detection")
show_labels = input.bool(true, "Show H/L Labels", group="Liquidity Detection")
// Group 2: Displacement Detection
enable_displacement = input.bool(true, "Enable Displacement Detection", group="Displacement")
displacement_multiplier = input.float(2.0, "Size Multiplier", minval=1.5, maxval=5.0, step=0.1, group="Displacement")
displacement_period = input.int(20, "Average Period", minval=10, maxval=50, group="Displacement")
displacement_color_bull = input.color(color.new(color.aqua, 70), "Bullish Color", group="Displacement")
displacement_color_bear = input.color(color.new(color.orange, 70), "Bearish Color", group="Displacement")
show_displacement_label = input.bool(true, "Show Labels", group="Displacement")
// Group 3: SMT Detection
enable_smt = input.bool(true, "Enable SMT Detection", group="SMT Divergence")
nq_symbol = input.string("NQ1!", "Nasdaq Symbol", group="SMT Divergence")
es_symbol = input.string("ES1!", "S&P500 Symbol", group="SMT Divergence")
smt_lookback = input.int(20, "Lookback Period", minval=5, maxval=100, group="SMT Divergence")
smt_line_color = input.color(color.yellow, "SMT Line Color", group="SMT Divergence")
smt_text_color = input.color(color.yellow, "SMT Text Color", group="SMT Divergence")
// ============================================
// ARRAYS FOR LINE/LABEL MANAGEMENT
// ============================================
var line[] high_lines = array.new_line()
var line[] low_lines = array.new_line()
var label[] high_labels = array.new_label()
var label[] low_labels = array.new_label()
var float[] high_levels = array.new_float()
var float[] low_levels = array.new_float()
// ============================================
// FUNCTION: DETECT SWING HIGHS
// ============================================
isSwingHigh(len) =>
highestBar = ta.highestbars(high, len * 2 + 1)
highestBar == -len
// ============================================
// FUNCTION: DETECT SWING LOWS
// ============================================
isSwingLow(len) =>
lowestBar = ta.lowestbars(low, len * 2 + 1)
lowestBar == -len
// ============================================
// SWING HIGH DETECTION & LINE DRAWING
// ============================================
if isSwingHigh(swing_length)
swing_high = high[swing_length]
new_line = line.new(bar_index - swing_length, swing_high, bar_index, swing_high, color=line_color_high, width=line_width, style=line.style_dashed)
array.push(high_lines, new_line)
array.push(high_levels, swing_high)
if show_labels
new_label = label.new(bar_index - swing_length, swing_high, "H", color=color.new(line_color_high, 80), textcolor=line_color_high, style=label.style_label_down, size=size.small)
array.push(high_labels, new_label)
// ============================================
// SWING LOW DETECTION & LINE DRAWING
// ============================================
if isSwingLow(swing_length)
swing_low = low[swing_length]
new_line = line.new(bar_index - swing_length, swing_low, bar_index, swing_low, color=line_color_low, width=line_width, style=line.style_dashed)
array.push(low_lines, new_line)
array.push(low_levels, swing_low)
if show_labels
new_label = label.new(bar_index - swing_length, swing_low, "L", color=color.new(line_color_low, 80), textcolor=line_color_low, style=label.style_label_up, size=size.small)
array.push(low_labels, new_label)
// ============================================
// UPDATE EXISTING LINES & CHECK FOR SWEEPS
// ============================================
if array.size(high_lines) > 0
for i = array.size(high_lines) - 1 to 0
current_line = array.get(high_lines, i)
current_level = array.get(high_levels, i)
if close > current_level
line.delete(current_line)
array.remove(high_lines, i)
array.remove(high_levels, i)
if show_labels and i < array.size(high_labels)
label.delete(array.get(high_labels, i))
array.remove(high_labels, i)
else
line.set_x2(current_line, bar_index)
if array.size(low_lines) > 0
for i = array.size(low_lines) - 1 to 0
current_line = array.get(low_lines, i)
current_level = array.get(low_levels, i)
if close < current_level
line.delete(current_line)
array.remove(low_lines, i)
array.remove(low_levels, i)
if show_labels and i < array.size(low_labels)
label.delete(array.get(low_labels, i))
array.remove(low_labels, i)
else
line.set_x2(current_line, bar_index)
// ============================================
// DISPLACEMENT CANDLE DETECTION
// ============================================
body_size = math.abs(close - open)
avg_body = ta.sma(math.abs(close - open), displacement_period)
is_displacement = enable_displacement and body_size > (avg_body * displacement_multiplier)
is_bullish = close > open
bgcolor(is_displacement ? (is_bullish ? displacement_color_bull : displacement_color_bear) : na)
if is_displacement and show_displacement_label
label.new(bar_index, is_bullish ? high : low, "D", color=color.new(is_bullish ? color.aqua : color.orange, 50), textcolor=is_bullish ? color.aqua : color.orange, style=is_bullish ? label.style_label_up : label.style_label_down, size=size.tiny)
// ============================================
// SMT DIVERGENCE DETECTION
// ============================================
current_symbol = syminfo.ticker
comparison_symbol = str.contains(current_symbol, "NQ") ? es_symbol : nq_symbol
comparison_high = request.security(comparison_symbol, timeframe.period, high, lookahead=barmerge.lookahead_off)
comparison_low = request.security(comparison_symbol, timeframe.period, low, lookahead=barmerge.lookahead_off)
var float prev_current_low = na
var float prev_comparison_low = na
var int prev_swing_bar = na
current_is_swing_low = isSwingLow(swing_length)
comparison_is_swing_low = ta.lowestbars(comparison_low, swing_length * 2 + 1) == -swing_length
if enable_smt and current_is_swing_low
current_swing_low = low[swing_length]
comparison_swing_low = comparison_low[swing_length]
if not na(prev_current_low) and not na(prev_comparison_low)
current_lower = current_swing_low < prev_current_low
comparison_lower = comparison_swing_low < prev_comparison_low
is_smt = (current_lower and not comparison_lower) or (not current_lower and comparison_lower)
if is_smt
smt_line = line.new(prev_swing_bar, prev_current_low, bar_index - swing_length, current_swing_low, color=smt_line_color, width=2, style=line.style_solid)
mid_bar = math.round((prev_swing_bar + bar_index - swing_length) / 2)
mid_price = (prev_current_low + current_swing_low) / 2
label.new(mid_bar, mid_price, "SMT", color=color.new(smt_line_color, 80), textcolor=smt_text_color, style=label.style_label_center, size=size.normal)
prev_current_low := current_swing_low
prev_comparison_low := comparison_swing_low
prev_swing_bar := bar_index - swing_length
// ============================================
// ALERTS
// ============================================
alertcondition(array.size(high_lines) < array.size(high_lines)[1], title="Liquidity Sweep High", message="High liquidity swept at {{close}}")
alertcondition(array.size(low_lines) < array.size(low_lines)[1], title="Liquidity Sweep Low", message="Low liquidity swept at {{close}}")
alertcondition(is_displacement, title="Displacement Candle", message="Displacement candle detected at {{close}}")
indicator("Liquidity & SMT Detector", overlay=true, max_lines_count=500, max_labels_count=500)
// ============================================
// INPUT SETTINGS
// ============================================
// Group 1: Liquidity Detection
swing_length = input.int(10, "Swing Length", minval=3, maxval=50, group="Liquidity Detection")
line_color_high = input.color(color.red, "High Line Color", group="Liquidity Detection")
line_color_low = input.color(color.green, "Low Line Color", group="Liquidity Detection")
line_width = input.int(2, "Line Width", minval=1, maxval=5, group="Liquidity Detection")
show_labels = input.bool(true, "Show H/L Labels", group="Liquidity Detection")
// Group 2: Displacement Detection
enable_displacement = input.bool(true, "Enable Displacement Detection", group="Displacement")
displacement_multiplier = input.float(2.0, "Size Multiplier", minval=1.5, maxval=5.0, step=0.1, group="Displacement")
displacement_period = input.int(20, "Average Period", minval=10, maxval=50, group="Displacement")
displacement_color_bull = input.color(color.new(color.aqua, 70), "Bullish Color", group="Displacement")
displacement_color_bear = input.color(color.new(color.orange, 70), "Bearish Color", group="Displacement")
show_displacement_label = input.bool(true, "Show Labels", group="Displacement")
// Group 3: SMT Detection
enable_smt = input.bool(true, "Enable SMT Detection", group="SMT Divergence")
nq_symbol = input.string("NQ1!", "Nasdaq Symbol", group="SMT Divergence")
es_symbol = input.string("ES1!", "S&P500 Symbol", group="SMT Divergence")
smt_lookback = input.int(20, "Lookback Period", minval=5, maxval=100, group="SMT Divergence")
smt_line_color = input.color(color.yellow, "SMT Line Color", group="SMT Divergence")
smt_text_color = input.color(color.yellow, "SMT Text Color", group="SMT Divergence")
// ============================================
// ARRAYS FOR LINE/LABEL MANAGEMENT
// ============================================
var line[] high_lines = array.new_line()
var line[] low_lines = array.new_line()
var label[] high_labels = array.new_label()
var label[] low_labels = array.new_label()
var float[] high_levels = array.new_float()
var float[] low_levels = array.new_float()
// ============================================
// FUNCTION: DETECT SWING HIGHS
// ============================================
isSwingHigh(len) =>
highestBar = ta.highestbars(high, len * 2 + 1)
highestBar == -len
// ============================================
// FUNCTION: DETECT SWING LOWS
// ============================================
isSwingLow(len) =>
lowestBar = ta.lowestbars(low, len * 2 + 1)
lowestBar == -len
// ============================================
// SWING HIGH DETECTION & LINE DRAWING
// ============================================
if isSwingHigh(swing_length)
swing_high = high[swing_length]
new_line = line.new(bar_index - swing_length, swing_high, bar_index, swing_high, color=line_color_high, width=line_width, style=line.style_dashed)
array.push(high_lines, new_line)
array.push(high_levels, swing_high)
if show_labels
new_label = label.new(bar_index - swing_length, swing_high, "H", color=color.new(line_color_high, 80), textcolor=line_color_high, style=label.style_label_down, size=size.small)
array.push(high_labels, new_label)
// ============================================
// SWING LOW DETECTION & LINE DRAWING
// ============================================
if isSwingLow(swing_length)
swing_low = low[swing_length]
new_line = line.new(bar_index - swing_length, swing_low, bar_index, swing_low, color=line_color_low, width=line_width, style=line.style_dashed)
array.push(low_lines, new_line)
array.push(low_levels, swing_low)
if show_labels
new_label = label.new(bar_index - swing_length, swing_low, "L", color=color.new(line_color_low, 80), textcolor=line_color_low, style=label.style_label_up, size=size.small)
array.push(low_labels, new_label)
// ============================================
// UPDATE EXISTING LINES & CHECK FOR SWEEPS
// ============================================
if array.size(high_lines) > 0
for i = array.size(high_lines) - 1 to 0
current_line = array.get(high_lines, i)
current_level = array.get(high_levels, i)
if close > current_level
line.delete(current_line)
array.remove(high_lines, i)
array.remove(high_levels, i)
if show_labels and i < array.size(high_labels)
label.delete(array.get(high_labels, i))
array.remove(high_labels, i)
else
line.set_x2(current_line, bar_index)
if array.size(low_lines) > 0
for i = array.size(low_lines) - 1 to 0
current_line = array.get(low_lines, i)
current_level = array.get(low_levels, i)
if close < current_level
line.delete(current_line)
array.remove(low_lines, i)
array.remove(low_levels, i)
if show_labels and i < array.size(low_labels)
label.delete(array.get(low_labels, i))
array.remove(low_labels, i)
else
line.set_x2(current_line, bar_index)
// ============================================
// DISPLACEMENT CANDLE DETECTION
// ============================================
body_size = math.abs(close - open)
avg_body = ta.sma(math.abs(close - open), displacement_period)
is_displacement = enable_displacement and body_size > (avg_body * displacement_multiplier)
is_bullish = close > open
bgcolor(is_displacement ? (is_bullish ? displacement_color_bull : displacement_color_bear) : na)
if is_displacement and show_displacement_label
label.new(bar_index, is_bullish ? high : low, "D", color=color.new(is_bullish ? color.aqua : color.orange, 50), textcolor=is_bullish ? color.aqua : color.orange, style=is_bullish ? label.style_label_up : label.style_label_down, size=size.tiny)
// ============================================
// SMT DIVERGENCE DETECTION
// ============================================
current_symbol = syminfo.ticker
comparison_symbol = str.contains(current_symbol, "NQ") ? es_symbol : nq_symbol
comparison_high = request.security(comparison_symbol, timeframe.period, high, lookahead=barmerge.lookahead_off)
comparison_low = request.security(comparison_symbol, timeframe.period, low, lookahead=barmerge.lookahead_off)
var float prev_current_low = na
var float prev_comparison_low = na
var int prev_swing_bar = na
current_is_swing_low = isSwingLow(swing_length)
comparison_is_swing_low = ta.lowestbars(comparison_low, swing_length * 2 + 1) == -swing_length
if enable_smt and current_is_swing_low
current_swing_low = low[swing_length]
comparison_swing_low = comparison_low[swing_length]
if not na(prev_current_low) and not na(prev_comparison_low)
current_lower = current_swing_low < prev_current_low
comparison_lower = comparison_swing_low < prev_comparison_low
is_smt = (current_lower and not comparison_lower) or (not current_lower and comparison_lower)
if is_smt
smt_line = line.new(prev_swing_bar, prev_current_low, bar_index - swing_length, current_swing_low, color=smt_line_color, width=2, style=line.style_solid)
mid_bar = math.round((prev_swing_bar + bar_index - swing_length) / 2)
mid_price = (prev_current_low + current_swing_low) / 2
label.new(mid_bar, mid_price, "SMT", color=color.new(smt_line_color, 80), textcolor=smt_text_color, style=label.style_label_center, size=size.normal)
prev_current_low := current_swing_low
prev_comparison_low := comparison_swing_low
prev_swing_bar := bar_index - swing_length
// ============================================
// ALERTS
// ============================================
alertcondition(array.size(high_lines) < array.size(high_lines)[1], title="Liquidity Sweep High", message="High liquidity swept at {{close}}")
alertcondition(array.size(low_lines) < array.size(low_lines)[1], title="Liquidity Sweep Low", message="Low liquidity swept at {{close}}")
alertcondition(is_displacement, title="Displacement Candle", message="Displacement candle detected at {{close}}")
Open-source Skript
Ganz im Sinne von TradingView hat dieser Autor sein/ihr Script als Open-Source veröffentlicht. Auf diese Weise können nun auch andere Trader das Script rezensieren und die Funktionalität überprüfen. Vielen Dank an den Autor! Sie können das Script kostenlos verwenden, aber eine Wiederveröffentlichung des Codes unterliegt unseren Hausregeln.
Haftungsausschluss
Die Informationen und Veröffentlichungen sind nicht als Finanz-, Anlage-, Handels- oder andere Arten von Ratschlägen oder Empfehlungen gedacht, die von TradingView bereitgestellt oder gebilligt werden, und stellen diese nicht dar. Lesen Sie mehr in den Nutzungsbedingungen.
Open-source Skript
Ganz im Sinne von TradingView hat dieser Autor sein/ihr Script als Open-Source veröffentlicht. Auf diese Weise können nun auch andere Trader das Script rezensieren und die Funktionalität überprüfen. Vielen Dank an den Autor! Sie können das Script kostenlos verwenden, aber eine Wiederveröffentlichung des Codes unterliegt unseren Hausregeln.
Haftungsausschluss
Die Informationen und Veröffentlichungen sind nicht als Finanz-, Anlage-, Handels- oder andere Arten von Ratschlägen oder Empfehlungen gedacht, die von TradingView bereitgestellt oder gebilligt werden, und stellen diese nicht dar. Lesen Sie mehr in den Nutzungsbedingungen.