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)
開源腳本
本著TradingView的真正精神,此腳本的創建者將其開源,以便交易者可以查看和驗證其功能。向作者致敬!雖然您可以免費使用它,但請記住,重新發佈程式碼必須遵守我們的網站規則。
免責聲明
這些資訊和出版物並不意味著也不構成TradingView提供或認可的金融、投資、交易或其他類型的意見或建議。請在使用條款閱讀更多資訊。
開源腳本
本著TradingView的真正精神,此腳本的創建者將其開源,以便交易者可以查看和驗證其功能。向作者致敬!雖然您可以免費使用它,但請記住,重新發佈程式碼必須遵守我們的網站規則。
免責聲明
這些資訊和出版物並不意味著也不構成TradingView提供或認可的金融、投資、交易或其他類型的意見或建議。請在使用條款閱讀更多資訊。