OPEN-SOURCE SCRIPT
Smart Harmonic Pattern Detector

//version=6
indicator("Smart Harmonic Pattern Detector", overlay=true, max_lines_count=500, max_labels_count=500)
// === User Input ===
zigzagDepth = input.int(12, title="ZigZag Depth")
bullColor = input.color(color.green, title="Bullish Signal Color")
bearColor = input.color(color.red, title="Bearish Signal Color")
textSize = input.string(size.small, title="Label Size")
// === Signal Detection Variables ===
var bool showBuySignal = false
var bool showSellSignal = false
var string signalDir = na
var int signalBar = na
// === ZigZag Pivot Logic ===
var float[] zz_prices = array.new_float()
var int[] zz_indexes = array.new_int()
var bool[] zz_types = array.new_bool() // true for high, false for low
ph = ta.pivothigh(high, zigzagDepth, zigzagDepth)
pl = ta.pivotlow(low, zigzagDepth, zigzagDepth)
if not na(ph)
array.push(zz_prices, ph)
array.push(zz_indexes, bar_index - zigzagDepth)
array.push(zz_types, true)
if not na(pl)
array.push(zz_prices, pl)
array.push(zz_indexes, bar_index - zigzagDepth)
array.push(zz_types, false)
// Reset signals
showBuySignal := false
showSellSignal := false
// === Pattern Detection ===
if array.size(zz_prices) >= 5
// Get last 5 points
float x = array.get(zz_prices, array.size(zz_prices)-5)
float a = array.get(zz_prices, array.size(zz_prices)-4)
float b = array.get(zz_prices, array.size(zz_prices)-3)
float c = array.get(zz_prices, array.size(zz_prices)-2)
float d = array.get(zz_prices, array.size(zz_prices)-1)
int x_i = array.get(zz_indexes, array.size(zz_indexes)-5)
int a_i = array.get(zz_indexes, array.size(zz_indexes)-4)
int b_i = array.get(zz_indexes, array.size(zz_indexes)-3)
int c_i = array.get(zz_indexes, array.size(zz_indexes)-2)
int d_i = array.get(zz_indexes, array.size(zz_indexes)-1)
bool x_type = array.get(zz_types, array.size(zz_types)-5)
bool a_type = array.get(zz_types, array.size(zz_types)-4)
bool b_type = array.get(zz_types, array.size(zz_types)-3)
bool c_type = array.get(zz_types, array.size(zz_types)-2)
bool d_type = array.get(zz_types, array.size(zz_types)-1)
// Validate swing structure
validStructure = (x_type != a_type) and (a_type != b_type) and (b_type != c_type) and (c_type != d_type)
if validStructure
// Calculate Fibonacci ratios
ab = math.abs(b - a)
bc = math.abs(c - b)
xa = math.abs(a - x)
cd = math.abs(d - c)
ab_pct = ab / xa
bc_pct = bc / ab
cd_pct = cd / bc
// Pattern detection
isBullish = false
isBearish = false
// Gartley Pattern
if (ab_pct >= 0.55 and ab_pct <= 0.65) and
(bc_pct >= 0.35 and bc_pct <= 0.45) and
(cd_pct >= 1.2 and cd_pct <= 1.35)
isBullish := not d_type
isBearish := d_type
// Bat Pattern
if (ab_pct >= 0.35 and ab_pct <= 0.45) and
(bc_pct >= 0.85 and bc_pct <= 0.9) and
(cd_pct >= 1.5 and cd_pct <= 1.7)
isBullish := not d_type
isBearish := d_type
// Current bar check
isCurrentBar = bar_index == d_i
// Set signal flags
if isCurrentBar and isBullish
showBuySignal := true
signalDir := "buy"
signalBar := bar_index
alert("Harmonic Buy signal detected", alert.freq_once_per_bar_close)
if isCurrentBar and isBearish
showSellSignal := true
signalDir := "sell"
signalBar := bar_index
alert("Harmonic Sell signal detected", alert.freq_once_per_bar_close)
// Draw labels
if isCurrentBar and (isBullish or isBearish)
label.new(
x = d_i,
y = d,
text = "→ " + (isBullish ? "buy" : "sell"),
style = d_type ? label.style_label_down : label.style_label_up,
color = (isBullish ? bullColor : bearColor),
textcolor = color.white
)
// === Plot Signals at Global Scope ===
plotshape(showBuySignal, title="Buy Signal", location=location.belowbar,
color=bullColor, style=shape.triangleup, size=size.normal)
plotshape(showSellSignal, title="Sell Signal", location=location.abovebar,
color=bearColor, style=shape.triangledown, size=size.normal)
indicator("Smart Harmonic Pattern Detector", overlay=true, max_lines_count=500, max_labels_count=500)
// === User Input ===
zigzagDepth = input.int(12, title="ZigZag Depth")
bullColor = input.color(color.green, title="Bullish Signal Color")
bearColor = input.color(color.red, title="Bearish Signal Color")
textSize = input.string(size.small, title="Label Size")
// === Signal Detection Variables ===
var bool showBuySignal = false
var bool showSellSignal = false
var string signalDir = na
var int signalBar = na
// === ZigZag Pivot Logic ===
var float[] zz_prices = array.new_float()
var int[] zz_indexes = array.new_int()
var bool[] zz_types = array.new_bool() // true for high, false for low
ph = ta.pivothigh(high, zigzagDepth, zigzagDepth)
pl = ta.pivotlow(low, zigzagDepth, zigzagDepth)
if not na(ph)
array.push(zz_prices, ph)
array.push(zz_indexes, bar_index - zigzagDepth)
array.push(zz_types, true)
if not na(pl)
array.push(zz_prices, pl)
array.push(zz_indexes, bar_index - zigzagDepth)
array.push(zz_types, false)
// Reset signals
showBuySignal := false
showSellSignal := false
// === Pattern Detection ===
if array.size(zz_prices) >= 5
// Get last 5 points
float x = array.get(zz_prices, array.size(zz_prices)-5)
float a = array.get(zz_prices, array.size(zz_prices)-4)
float b = array.get(zz_prices, array.size(zz_prices)-3)
float c = array.get(zz_prices, array.size(zz_prices)-2)
float d = array.get(zz_prices, array.size(zz_prices)-1)
int x_i = array.get(zz_indexes, array.size(zz_indexes)-5)
int a_i = array.get(zz_indexes, array.size(zz_indexes)-4)
int b_i = array.get(zz_indexes, array.size(zz_indexes)-3)
int c_i = array.get(zz_indexes, array.size(zz_indexes)-2)
int d_i = array.get(zz_indexes, array.size(zz_indexes)-1)
bool x_type = array.get(zz_types, array.size(zz_types)-5)
bool a_type = array.get(zz_types, array.size(zz_types)-4)
bool b_type = array.get(zz_types, array.size(zz_types)-3)
bool c_type = array.get(zz_types, array.size(zz_types)-2)
bool d_type = array.get(zz_types, array.size(zz_types)-1)
// Validate swing structure
validStructure = (x_type != a_type) and (a_type != b_type) and (b_type != c_type) and (c_type != d_type)
if validStructure
// Calculate Fibonacci ratios
ab = math.abs(b - a)
bc = math.abs(c - b)
xa = math.abs(a - x)
cd = math.abs(d - c)
ab_pct = ab / xa
bc_pct = bc / ab
cd_pct = cd / bc
// Pattern detection
isBullish = false
isBearish = false
// Gartley Pattern
if (ab_pct >= 0.55 and ab_pct <= 0.65) and
(bc_pct >= 0.35 and bc_pct <= 0.45) and
(cd_pct >= 1.2 and cd_pct <= 1.35)
isBullish := not d_type
isBearish := d_type
// Bat Pattern
if (ab_pct >= 0.35 and ab_pct <= 0.45) and
(bc_pct >= 0.85 and bc_pct <= 0.9) and
(cd_pct >= 1.5 and cd_pct <= 1.7)
isBullish := not d_type
isBearish := d_type
// Current bar check
isCurrentBar = bar_index == d_i
// Set signal flags
if isCurrentBar and isBullish
showBuySignal := true
signalDir := "buy"
signalBar := bar_index
alert("Harmonic Buy signal detected", alert.freq_once_per_bar_close)
if isCurrentBar and isBearish
showSellSignal := true
signalDir := "sell"
signalBar := bar_index
alert("Harmonic Sell signal detected", alert.freq_once_per_bar_close)
// Draw labels
if isCurrentBar and (isBullish or isBearish)
label.new(
x = d_i,
y = d,
text = "→ " + (isBullish ? "buy" : "sell"),
style = d_type ? label.style_label_down : label.style_label_up,
color = (isBullish ? bullColor : bearColor),
textcolor = color.white
)
// === Plot Signals at Global Scope ===
plotshape(showBuySignal, title="Buy Signal", location=location.belowbar,
color=bullColor, style=shape.triangleup, size=size.normal)
plotshape(showSellSignal, title="Sell Signal", location=location.abovebar,
color=bearColor, style=shape.triangledown, size=size.normal)
Skrip sumber terbuka
Dalam semangat sebenar TradingView, pencipta skrip ini telah menjadikannya sumber terbuka supaya pedagang dapat menilai dan mengesahkan kefungsiannya. Terima kasih kepada penulis! Walaupun anda boleh menggunakannya secara percuma, ingat bahawa menerbitkan semula kod ini adalah tertakluk kepada Peraturan Dalaman kami.
Penafian
Maklumat dan penerbitan adalah tidak dimaksudkan untuk menjadi, dan tidak membentuk, nasihat untuk kewangan, pelaburan, perdagangan dan jenis-jenis lain atau cadangan yang dibekalkan atau disahkan oleh TradingView. Baca dengan lebih lanjut di Terma Penggunaan.
Skrip sumber terbuka
Dalam semangat sebenar TradingView, pencipta skrip ini telah menjadikannya sumber terbuka supaya pedagang dapat menilai dan mengesahkan kefungsiannya. Terima kasih kepada penulis! Walaupun anda boleh menggunakannya secara percuma, ingat bahawa menerbitkan semula kod ini adalah tertakluk kepada Peraturan Dalaman kami.
Penafian
Maklumat dan penerbitan adalah tidak dimaksudkan untuk menjadi, dan tidak membentuk, nasihat untuk kewangan, pelaburan, perdagangan dan jenis-jenis lain atau cadangan yang dibekalkan atau disahkan oleh TradingView. Baca dengan lebih lanjut di Terma Penggunaan.