Indicator · Pine Script v5 · On the chart

Harmonic Pattern Manual and Auto

by ggne

An overlay with Turkish labels that detects XABCD harmonic patterns, including Gartley, Bat, Butterfly, Crab, Deep Crab, Shark and Cypher.

View on GitHub

Repaints

GitHub stars1on the repository
Pine versionv5runs as is
Lines of code760
Settings29inputs
LicenceMIT
Last update1 year ago24 Sep 2025

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

760 lines of Pine Script v5 from src/harmonic-pattern-v5.pine, published under MIT. Keep the author's credit and licence lines when you reuse it.

harmonic-pattern-v5.pine
//@version=5
indicator("Harmonik Desen - Manuel ve Otomatik", overlay=true, max_lines_count=500, max_labels_count=500, max_bars_back=500)

// =========================================
// TÜR TANIMLARI
// =========================================
type userPoint
    float price
    int   time
    int   bar

type HarmonicPattern
    string name
    float xab_min
    float xab_max
    float abc_min
    float abc_max
    float bcd_min
    float bcd_max
    float xad_min
    float xad_max

type DPrediction
    string pattern_name
    float d_price
    float confidence
    color pattern_color
    float xad_ratio

type AutoPattern
    int xBar
    float xPrice
    int aBar
    float aPrice
    int bBar
    float bPrice
    int cBar
    float cPrice
    int dBar
    float dPrice
    bool isBullish
    string patternType
    float score
    bool isComplete

// =========================================
// GLOBAL DEĞİŞKENLER
// =========================================
var line[] lines = array.new_line(0)
var label[] labels = array.new_label(0)
var box[] boxes = array.new_box(0)
var table infoTable = table.new(position.top_right, 2, 16, bgcolor=color.new(color.black, 80))
var AutoPattern[] autoPatterns = array.new<AutoPattern>()
var line[] autoLines = array.new_line(0)
var label[] autoLabels = array.new_label(0)

// =========================================
// GİRDİLER
// =========================================
mode = input.string("Otomatik", "Çalışma Modu", options=["Manuel", "Otomatik", "Her İkisi"], group="Genel Ayarlar")
xP = input.price(0, "X", group="Manuel XABC Noktaları", inline="X", confirm=true)
xT = input.time(0, "", group="Manuel XABC Noktaları", inline="X", confirm=true)
aP = input.price(0, "A", group="Manuel XABC Noktaları", inline="A", confirm=true)
aT = input.time(0, "", group="Manuel XABC Noktaları", inline="A", confirm=true)
bP = input.price(0, "B", group="Manuel XABC Noktaları", inline="B", confirm=true)
bT = input.time(0, "", group="Manuel XABC Noktaları", inline="B", confirm=true)
cP = input.price(0, "C", group="Manuel XABC Noktaları", inline="C", confirm=true)
cT = input.time(0, "", group="Manuel XABC Noktaları", inline="C", confirm=true)
dP = input.price(0, "D", group="Manuel XABC Noktaları", inline="D", confirm=true)
dT = input.time(0, "", group="Manuel XABC Noktaları", inline="D", confirm=true)
auto_lookback = input.int(100, "Geriye Bakış Periyodu", minval=50, maxval=500, group="Otomatik Tespit")
auto_min_score = input.float(60.0, "Minimum Skor %", minval=0, maxval=100, group="Otomatik Tespit")
auto_show_potential = input.bool(true, "Potansiyel Desenleri Göster", group="Otomatik Tespit")
pivot_length = input.int(5, "Pivot Uzunluğu", minval=3, maxval=20, group="Otomatik Tespit")
use_manual_d = input.bool(false, "D Noktasını Manuel Kullan", group="D Noktası Ayarları")
show_all_d_predictions = input.bool(true, "Tüm D Tahminlerini Göster", group="D Noktası Ayarları")
min_confidence = input.float(50.0, "Minimum Güven Skoru %", minval=0, maxval=100, group="D Noktası Ayarları")
show_d_zone = input.bool(true, "D Hedef Bölgesini Göster", group="Görüntüleme")
show_projections = input.bool(true, "C'den D'ye İzdüşüm Çizgileri", group="Görüntüleme")
show_ratios = input.bool(true, "Harmonik Oranları Göster", group="Görüntüleme")
show_pattern_info = input.bool(true, "Desen Bilgi Tablosunu Göster", group="Görüntüleme")
highlight_best_d = input.bool(true, "En İyi D Tahminini Vurgula", group="Görüntüleme")
tolerance = input.float(0.15, "Desen Toleransı", minval=0.01, maxval=0.3, step=0.01, group="Desen Tanıma")
pctAsym = input.float(250.0, "İzin verilen bacak uzunluğu asimetrisi %", step=1.0, minval=0.0, maxval=1000.0, group="Desen Tanıma")
c_bull_manual = input.color(color.new(color.green, 20), "Manuel Boğa Rengi", group="Renkler")
c_bear_manual = input.color(color.new(color.red, 20), "Manuel Ayı Rengi", group="Renkler")
c_bull_auto = input.color(color.new(color.blue, 40), "Otomatik Boğa Rengi", group="Renkler")
c_bear_auto = input.color(color.new(color.orange, 40), "Otomatik Ayı Rengi", group="Renkler")

// =========================================
// HARMONİK DESEN TANIMLARI
// =========================================
f_define_patterns() =>
    patterns = array.new<HarmonicPattern>()
    array.push(patterns, HarmonicPattern.new("Gartley", 0.618, 0.618, 0.382, 0.886, 1.13, 1.618, 0.786, 0.786))
    array.push(patterns, HarmonicPattern.new("Bat", 0.382, 0.50, 0.382, 0.886, 1.618, 2.618, 0.886, 0.886))
    array.push(patterns, HarmonicPattern.new("Butterfly", 0.786, 0.786, 0.382, 0.886, 1.618, 2.24, 1.27, 1.27))
    array.push(patterns, HarmonicPattern.new("Crab", 0.382, 0.618, 0.382, 0.886, 2.618, 3.618, 1.618, 1.618))
    array.push(patterns, HarmonicPattern.new("Deep Crab", 0.886, 0.886, 0.382, 0.886, 2.0, 3.618, 1.618, 1.618))
    array.push(patterns, HarmonicPattern.new("Shark", 0.446, 0.618, 1.13, 1.618, 1.618, 2.24, 0.886, 1.13))
    array.push(patterns, HarmonicPattern.new("Cypher", 0.382, 0.618, 1.13, 1.41, 1.27, 2.00, 0.786, 0.786))
    patterns

f_get_pattern_color(pattern_name) =>
    switch pattern_name
        "Gartley" => color.green
        "Bat" => color.blue
        "Butterfly" => color.orange
        "Crab" => color.red
        "Deep Crab" => color.maroon
        "Shark" => color.purple
        "Cypher" => color.teal
        => color.gray

// =========================================
// TEMİZLEME
// =========================================
f_clear_all() =>
    for l in lines
        line.delete(l)
    for lbl in labels
        label.delete(lbl)
    for b in boxes
        box.delete(b)
    array.clear(lines)
    array.clear(labels)
    array.clear(boxes)

f_clear_auto() =>
    for l in autoLines
        line.delete(l)
    for lbl in autoLabels
        label.delete(lbl)
    array.clear(autoLines)
    array.clear(autoLabels)

// =========================================
// ORAN HESAPLAMA
// =========================================
f_calculate_ratios(x, a, b, c, d) =>
    xa = math.abs(a - x)
    ab = math.abs(b - a)
    bc = math.abs(c - b)
    cd = math.abs(d - c)
    ad = math.abs(d - a)
    xab = xa != 0 ? ab / xa : 0
    abc = ab != 0 ? bc / ab : 0
    bcd = bc != 0 ? cd / bc : 0
    xad = xa != 0 ? ad / xa : 0
    [xab, abc, bcd, xad]

// =========================================
// OTOMATİK DESEN TESPİT FONKSİYONLARI
// =========================================
f_isPivotHigh(src, left, right, index) =>
    isHigh = true
    for i = 1 to left
        if index + i <= bar_index and src[index + i] >= src[index]
            isHigh := false
            break
    if isHigh
        for i = 1 to right
            if index - i >= 0 and src[index - i] >= src[index]
                isHigh := false
                break
    isHigh

f_isPivotLow(src, left, right, index) =>
    isLow = true
    for i = 1 to left
        if index + i <= bar_index and src[index + i] <= src[index]
            isLow := false
            break
    if isLow
        for i = 1 to right
            if index - i >= 0 and src[index - i] <= src[index]
                isLow := false
                break
    isLow

f_test_symmetry(leg1, leg2, leg3, leg4, asymPct) =>
    legs = array.from(leg1, leg2, leg3, leg4)
    avgLen = array.avg(legs)
    valid = true
    if avgLen > 0
        for i = 0 to 3
            legLen = array.get(legs, i)
            if math.abs(legLen - avgLen) / avgLen > asymPct / 100
                valid := false
                break
    valid

f_check_harmonic_ratios(xab, abc, bcd, xad, pattern, tol) =>
    xab_valid = xab >= pattern.xab_min * (1 - tol) and xab <= pattern.xab_max * (1 + tol)
    abc_valid = abc >= pattern.abc_min * (1 - tol) and abc <= pattern.abc_max * (1 + tol)
    bcd_valid = bcd >= pattern.bcd_min * (1 - tol) and bcd <= pattern.bcd_max * (1 + tol)
    xad_valid = xad >= pattern.xad_min * (1 - tol) and xad <= pattern.xad_max * (1 + tol)
    score = 0.0
    if xab_valid
        score += 25
    if abc_valid
        score += 25
    if bcd_valid
        score += 25
    if xad_valid
        score += 25
    [xab_valid and abc_valid and bcd_valid and xad_valid, score]

f_validate_pattern(xBar, xPrice, aBar, aPrice, bBar, bPrice, cBar, cPrice, dBar, dPrice, isBullish) =>
    patterns = f_define_patterns()
    validPatterns = array.new<string>()
    patternScores = array.new<float>()
    [xab, abc, bcd, xad] = f_calculate_ratios(xPrice, aPrice, bPrice, cPrice, dPrice)
    for pattern in patterns
        [isValid, score] = f_check_harmonic_ratios(xab, abc, bcd, xad, pattern, tolerance)
        if isValid and score >= auto_min_score
            array.push(validPatterns, pattern.name)
            array.push(patternScores, score)
    [validPatterns, patternScores]

f_find_auto_patterns() =>
    lookback = math.min(auto_lookback, 500)
    highs = array.new<int>()
    lows = array.new<int>()
    
    for i = pivot_length to lookback - pivot_length
        if i <= bar_index
            if f_isPivotHigh(high, pivot_length, pivot_length, i)
                array.push(highs, i)
            if f_isPivotLow(low, pivot_length, pivot_length, i)
                array.push(lows, i)
    
    // Debug: Pivot sayılarını tabloya ekle
    if barstate.islast
        table.cell(infoTable, 0, 15, "Pivot Highs/Lows", bgcolor=color.new(color.gray, 80), text_color=color.white)
        table.cell(infoTable, 1, 15, str.tostring(array.size(highs)) + "/" + str.tostring(array.size(lows)), text_color=color.white)
    
    // Pivot sayısı kontrolü
    if array.size(lows) >= 3 and array.size(highs) >= 2
        // Boğa desenleri (X=low, A=high, B=low, C=high, D=low)
        for d = 0 to math.min(array.size(lows) - 1, 10)
            dIdx = array.get(lows, d)
            dBar = bar_index - dIdx
            dPrice = low[dIdx]
            for c = 0 to math.min(array.size(highs) - 1, 10)
                cIdx = array.get(highs, c)
                if cIdx > dIdx
                    cBar = bar_index - cIdx
                    cPrice = high[cIdx]
                    for b = d + 1 to math.min(array.size(lows) - 2, 15)
                        if b >= array.size(lows)
                            break
                        bIdx = array.get(lows, b)
                        if bIdx > cIdx
                            bBar = bar_index - bIdx
                            bPrice = low[bIdx]
                            xa = math.abs(cPrice - bPrice)
                            ab = math.abs(bPrice - cPrice)
                            xab = xa != 0 ? ab / xa : 0
                            if not (xab >= 0.382 * (1 - tolerance) and xab <= 1.618 * (1 + tolerance))
                                continue
                            for a = c + 1 to math.min(array.size(highs) - 2, 15)
                                if a >= array.size(highs)
                                    break
                                aIdx = array.get(highs, a)
                                if aIdx > bIdx
                                    aBar = bar_index - aIdx
                                    aPrice = high[aIdx]
                                    for x = b + 1 to math.min(array.size(lows) - 2, 20)
                                        if x >= array.size(lows)
                                            break
                                        xIdx = array.get(lows, x)
                                        if xIdx > aIdx
                                            xBar = bar_index - xIdx
                                            xPrice = low[xIdx]
                                            if not f_test_symmetry(aBar-xBar, bBar-aBar, cBar-bBar, dBar-cBar, pctAsym)
                                                continue
                                            [validPatterns, patternScores] = f_validate_pattern(xBar, xPrice, aBar, aPrice, bBar, bPrice, cBar, cPrice, dBar, dPrice, true)
                                            if array.size(validPatterns) > 0
                                                maxScore = array.max(patternScores)
                                                bestPattern = array.get(validPatterns, array.indexof(patternScores, maxScore))
                                                pattern = AutoPattern.new()
                                                pattern.xBar := xBar
                                                pattern.xPrice := xPrice
                                                pattern.aBar := aBar
                                                pattern.aPrice := aPrice
                                                pattern.bBar := bBar
                                                pattern.bPrice := bPrice
                                                pattern.cBar := cBar
                                                pattern.cPrice := cPrice
                                                pattern.dBar := dBar
                                                pattern.dPrice := dPrice
                                                pattern.isBullish := true
                                                pattern.patternType := bestPattern
                                                pattern.score := maxScore
                                                pattern.isComplete := true
                                                exists = false
                                                for p in autoPatterns
                                                    if p.xBar == xBar and p.aBar == aBar and p.bBar == bBar and p.cBar == cBar and p.dBar == dBar
                                                        exists := true
                                                        break
                                                if not exists
                                                    array.push(autoPatterns, pattern)
        
        // Ayı desenleri (X=high, A=low, B=high, C=low, D=high)
        for d = 0 to math.min(array.size(highs) - 1, 10)
            dIdx = array.get(highs, d)
            dBar = bar_index - dIdx
            dPrice = high[dIdx]
            for c = 0 to math.min(array.size(lows) - 1, 10)
                cIdx = array.get(lows, c)
                if cIdx > dIdx
                    cBar = bar_index - cIdx
                    cPrice = low[cIdx]
                    for b = d + 1 to math.min(array.size(highs) - 2, 15)
                        if b >= array.size(highs)
                            break
                        bIdx = array.get(highs, b)
                        if bIdx > cIdx
                            bBar = bar_index - bIdx
                            bPrice = high[bIdx]
                            xa = math.abs(cPrice - bPrice)
                            ab = math.abs(bPrice - cPrice)
                            xab = xa != 0 ? ab / xa : 0
                            if not (xab >= 0.382 * (1 - tolerance) and xab <= 1.618 * (1 + tolerance))
                                continue
                            for a = c + 1 to math.min(array.size(lows) - 2, 15)
                                if a >= array.size(lows)
                                    break
                                aIdx = array.get(lows, a)
                                if aIdx > bIdx
                                    aBar = bar_index - aIdx
                                    aPrice = low[aIdx]
                                    for x = b + 1 to math.min(array.size(highs) - 2, 20)
                                        if x >= array.size(highs)
                                            break
                                        xIdx = array.get(highs, x)
                                        if xIdx > aIdx
                                            xBar = bar_index - xIdx
                                            xPrice = high[xIdx]
                                            if not f_test_symmetry(aBar-xBar, bBar-aBar, cBar-bBar, dBar-cBar, pctAsym)
                                                continue
                                            [validPatterns, patternScores] = f_validate_pattern(xBar, xPrice, aBar, aPrice, bBar, bPrice, cBar, cPrice, dBar, dPrice, false)
                                            if array.size(validPatterns) > 0
                                                maxScore = array.max(patternScores)
                                                bestPattern = array.get(validPatterns, array.indexof(patternScores, maxScore))
                                                pattern = AutoPattern.new()
                                                pattern.xBar := xBar
                                                pattern.xPrice := xPrice
                                                pattern.aBar := aBar
                                                pattern.aPrice := aPrice
                                                pattern.bBar := bBar
                                                pattern.bPrice := bPrice
                                                pattern.cBar := cBar
                                                pattern.cPrice := cPrice
                                                pattern.dBar := dBar
                                                pattern.dPrice := dPrice
                                                pattern.isBullish := false
                                                pattern.patternType := bestPattern
                                                pattern.score := maxScore
                                                pattern.isComplete := true
                                                exists = false
                                                for p in autoPatterns
                                                    if p.xBar == xBar and p.aBar == aBar and p.bBar == bBar and p.cBar == cBar and p.dBar == dBar
                                                        exists := true
                                                        break
                                                if not exists
                                                    array.push(autoPatterns, pattern)
        
        // Potansiyel desenler
        if auto_show_potential
            for c = 0 to math.min(array.size(highs) - 1, 5)
                cIdx = array.get(highs, c)
                cBar = bar_index - cIdx
                cPrice = high[cIdx]
                for b = 0 to math.min(array.size(lows) - 1, 10)
                    bIdx = array.get(lows, b)
                    if bIdx > cIdx
                        bBar = bar_index - bIdx
                        bPrice = low[bIdx]
                        xa = math.abs(cPrice - bPrice)
                        ab = math.abs(bPrice - cPrice)
                        xab = xa != 0 ? ab / xa : 0
                        if not (xab >= 0.382 * (1 - tolerance) and xab <= 1.618 * (1 + tolerance))
                            continue
                        for a = c + 1 to math.min(array.size(highs) - 2, 15)
                            if a >= array.size(highs)
                                break
                            aIdx = array.get(highs, a)
                            if aIdx > bIdx
                                aBar = bar_index - aIdx
                                aPrice = high[aIdx]
                                for x = b + 1 to math.min(array.size(lows) - 2, 20)
                                    if x >= array.size(lows)
                                        break
                                    xIdx = array.get(lows, x)
                                    if xIdx > aIdx
                                        xBar = bar_index - xIdx
                                        xPrice = low[xIdx]
                                        xa = math.abs(aPrice - xPrice)
                                        ab = math.abs(bPrice - aPrice)
                                        bc = math.abs(cPrice - bPrice)
                                        xab = xa != 0 ? ab / xa : 0
                                        abc = ab != 0 ? bc / ab : 0
                                        if xab > 0 and abc > 0
                                            patterns = f_define_patterns()
                                            for pat in patterns
                                                xab_valid = xab >= pat.xab_min * (1 - tolerance) and xab <= pat.xab_max * (1 + tolerance)
                                                abc_valid = abc >= pat.abc_min * (1 - tolerance) and abc <= pat.abc_max * (1 + tolerance)
                                                if xab_valid and abc_valid
                                                    pattern = AutoPattern.new()
                                                    pattern.xBar := xBar
                                                    pattern.xPrice := xPrice
                                                    pattern.aBar := aBar
                                                    pattern.aPrice := aPrice
                                                    pattern.bBar := bBar
                                                    pattern.bPrice := bPrice
                                                    pattern.cBar := cBar
                                                    pattern.cPrice := cPrice
                                                    pattern.dBar := na
                                                    pattern.dPrice := na
                                                    pattern.isBullish := true
                                                    pattern.patternType := pat.name
                                                    pattern.score := 50.0
                                                    pattern.isComplete := false
                                                    exists = false
                                                    for p in autoPatterns
                                                        if p.xBar == xBar and p.aBar == aBar and p.bBar == bBar and p.cBar == cBar and not p.isComplete
                                                            exists := true
                                                            break
                                                    if not exists
                                                        array.push(autoPatterns, pattern)
                                                    break

// =========================================
// GÜVEN SKORU HESAPLAMA
// =========================================
f_calculate_pattern_confidence(xab, abc, pattern) =>
    xab_mid = (pattern.xab_min + pattern.xab_max) / 2
    xab_range = pattern.xab_max - pattern.xab_min
    xab_deviation = xab_range > 0 ? math.abs(xab - xab_mid) / (xab_range / 2) : 1
    xab_score = math.max(0, 100 * (1 - xab_deviation))
    abc_mid = (pattern.abc_min + pattern.abc_max) / 2
    abc_range = pattern.abc_max - pattern.abc_min
    abc_deviation = abc_range > 0 ? math.abs(abc - abc_mid) / (abc_range / 2) : 1
    abc_score = math.max(0, 100 * (1 - abc_deviation))
    confidence = (xab_score * 0.6 + abc_score * 0.4)
    confidence

// =========================================
// ÇOKLU D TAHMİNİ
// =========================================
f_calculate_multiple_d_predictions(x, a, b, c) =>
    predictions = array.new<DPrediction>()
    patterns = f_define_patterns()
    xa = math.abs(a - x)
    ab = math.abs(b - a)
    bc = math.abs(c - b)
    xab = xa != 0 ? ab / xa : 0
    abc = ab != 0 ? bc / ab : 0
    trend_up = a > x
    for pattern in patterns
        confidence = f_calculate_pattern_confidence(xab, abc, pattern)
        if confidence >= min_confidence
            ideal_xad = (pattern.xad_min + pattern.xad_max) / 2
            ad_distance = xa * ideal_xad
            d_price = trend_up ? a - ad_distance : a + ad_distance
            prediction = DPrediction.new(pattern.name, d_price, confidence, f_get_pattern_color(pattern.name), ideal_xad)
            array.push(predictions, prediction)
    n = array.size(predictions)
    if n > 1
        for i = 0 to n - 2
            for j = 0 to n - i - 2
                if array.get(predictions, j).confidence < array.get(predictions, j + 1).confidence
                    temp = array.get(predictions, j)
                    array.set(predictions, j, array.get(predictions, j + 1))
                    array.set(predictions, j + 1, temp)
    predictions

// =========================================
// OTOMATİK DESEN ÇİZİMİ
// =========================================
f_draw_auto_pattern(pattern) =>
    lineColor = pattern.isBullish ? c_bull_auto : c_bear_auto
    xa_line = line.new(pattern.xBar, pattern.xPrice, pattern.aBar, pattern.aPrice, color=lineColor, width=2)
    ab_line = line.new(pattern.aBar, pattern.aPrice, pattern.bBar, pattern.bPrice, color=lineColor, width=2)
    bc_line = line.new(pattern.bBar, pattern.bPrice, pattern.cBar, pattern.cPrice, color=lineColor, width=2)
    array.push(autoLines, xa_line)
    array.push(autoLines, ab_line)
    array.push(autoLines, bc_line)
    if pattern.isComplete
        cd_line = line.new(pattern.cBar, pattern.cPrice, pattern.dBar, pattern.dPrice, color=lineColor, width=2)
        array.push(autoLines, cd_line)
    xb_line = line.new(pattern.xBar, pattern.xPrice, pattern.bBar, pattern.bPrice, color=color.new(lineColor, 50), width=1, style=line.style_dashed)
    ac_line = line.new(pattern.aBar, pattern.aPrice, pattern.cBar, pattern.cPrice, color=color.new(lineColor, 50), width=1, style=line.style_dotted)
    array.push(autoLines, xb_line)
    array.push(autoLines, ac_line)
    if pattern.isComplete
        bd_line = line.new(pattern.bBar, pattern.bPrice, pattern.dBar, pattern.dPrice, color=color.new(lineColor, 50), width=1, style=line.style_dashed)
        xd_line = line.new(pattern.xBar, pattern.xPrice, pattern.dBar, pattern.dPrice, color=color.new(lineColor, 50), width=1, style=line.style_dotted)
        array.push(autoLines, bd_line)
        array.push(autoLines, xd_line)
    x_label = label.new(pattern.xBar, pattern.xPrice, "X", style=label.style_circle, color=color.white, textcolor=color.black, size=size.tiny)
    a_label = label.new(pattern.aBar, pattern.aPrice, "A", style=label.style_circle, color=color.white, textcolor=color.black, size=size.tiny)
    b_label = label.new(pattern.bBar, pattern.bPrice, "B", style=label.style_circle, color=color.white, textcolor=color.black, size=size.tiny)
    c_label = label.new(pattern.cBar, pattern.cPrice, "C", style=label.style_circle, color=color.white, textcolor=color.black, size=size.tiny)
    array.push(autoLabels, x_label)
    array.push(autoLabels, a_label)
    array.push(autoLabels, b_label)
    array.push(autoLabels, c_label)
    if pattern.isComplete
        d_label = label.new(pattern.dBar, pattern.dPrice, "D", style=label.style_circle, color=color.white, textcolor=color.black, size=size.tiny)
        array.push(autoLabels, d_label)
    labelText = pattern.patternType + " (" + str.tostring(pattern.score, "#.#") + "%)"
    if not pattern.isComplete
        labelText := "Potansiyel " + labelText
    pattern_label = label.new(pattern.cBar, pattern.cPrice, labelText, style=label.style_label_down, color=color.new(lineColor, 80), textcolor=color.white, size=size.small)
    array.push(autoLabels, pattern_label)
    if not pattern.isComplete and auto_show_potential
        predictions = f_calculate_multiple_d_predictions(pattern.xPrice, pattern.aPrice, pattern.bPrice, pattern.cPrice)
        if array.size(predictions) > 0
            best_pred = array.get(predictions, 0)
            d_line = line.new(pattern.cBar, pattern.cPrice, pattern.cBar + 20, best_pred.d_price, color=color.new(lineColor, 50), width=2, style=line.style_dashed)
            array.push(autoLines, d_line)
            d_label = label.new(pattern.cBar + 20, best_pred.d_price, "D?", style=label.style_circle, color=color.purple, textcolor=color.white, size=size.tiny)
            array.push(autoLabels, d_label)

// =========================================
// BAR İNDEKS BULMA
// =========================================
f_resolveBarIndex(array<userPoint> pts) =>
    for offset = 0 to 999
        for p in pts
            if na(p.bar) and time[offset] == p.time
                p.bar := bar_index - offset

// =========================================
// D BÖLGESİ ÇİZİMİ - ÇOKLU
// =========================================
f_draw_multiple_d_zones(predictions, cBar, c) =>
    if array.size(predictions) > 0
        best_prediction = array.get(predictions, 0)
        all_d_prices = array.new<float>()
        for pred in predictions
            array.push(all_d_prices, pred.d_price)
        d_min = array.min(all_d_prices)
        d_max = array.max(all_d_prices)
        if show_d_zone
            box_left = cBar + 5
            box_right = cBar + 30
            prz_box = box.new(box_left, d_max, box_right, d_min, border_color=color.purple, border_width=2, bgcolor=color.new(color.purple, 95))
            box.set_text(prz_box, "D Hedef Bölgesi\n" + str.tostring(d_min, "#.##") + " - " + str.tostring(d_max, "#.##"))
            box.set_text_color(prz_box, color.white)
            box.set_text_halign(prz_box, text.align_center)
            box.set_text_size(prz_box, size.small)
            array.push(boxes, prz_box)
        max_predictions_to_show = show_all_d_predictions ? array.size(predictions) : math.min(3, array.size(predictions))
        for i = 0 to max_predictions_to_show - 1
            pred = array.get(predictions, i)
            line_width = (i == 0 and highlight_best_d) ? 3 : 1
            line_style = i == 0 ? line.style_solid : line.style_dashed
            level_line = line.new(cBar + 5, pred.d_price, cBar + 30, pred.d_price, color=pred.pattern_color, width=line_width, style=line_style)
            array.push(lines, level_line)
            label_text = pred.pattern_name + "\n" + str.tostring(pred.confidence, "#") + "%" + "\n" + "XAD: " + str.tostring(pred.xad_ratio, "#.###")
            level_label = label.new(cBar + 32, pred.d_price, label_text, style=label.style_label_left, color=color.new(pred.pattern_color, 80), textcolor=color.white, size=size.small)
            array.push(labels, level_label)
            if show_projections
                proj_line = line.new(cBar, c, cBar + 5, pred.d_price, color=color.new(pred.pattern_color, 70), width=1, style=line.style_dotted)
                array.push(lines, proj_line)

// =========================================
// MANUEL DESEN ÇİZİMİ
// =========================================
f_draw_pattern(x, a, b, c, d, xBar, aBar, bBar, cBar, dBar, isAutoD) =>
    lineColor = a > x ? c_bull_manual : c_bear_manual
    array.push(lines, line.new(xBar, x, aBar, a, color=lineColor, width=2))
    array.push(lines, line.new(aBar, a, bBar, b, color=lineColor, width=2))
    array.push(lines, line.new(bBar, b, cBar, c, color=lineColor, width=2))
    cd_line_style = isAutoD ? line.style_dashed : line.style_solid
    array.push(lines, line.new(cBar, c, dBar, d, color=lineColor, width=2, style=cd_line_style))
    array.push(lines, line.new(xBar, x, bBar, b, color=color.new(lineColor, 50), width=1, style=line.style_dashed))
    array.push(lines, line.new(aBar, a, cBar, c, color=color.new(lineColor, 50), width=1, style=line.style_dotted))
    if not na(d)
        array.push(lines, line.new(bBar, b, dBar, d, color=color.new(lineColor, 50), width=1, style=line.style_dashed))
        array.push(lines, line.new(xBar, x, dBar, d, color=color.new(lineColor, 50), width=1, style=line.style_dotted))
    array.push(labels, label.new(xBar, x, "X", style=label.style_circle, color=color.white, textcolor=color.black, size=size.tiny))
    array.push(labels, label.new(aBar, a, "A", style=label.style_circle, color=color.white, textcolor=color.black, size=size.tiny))
    array.push(labels, label.new(bBar, b, "B", style=label.style_circle, color=color.white, textcolor=color.black, size=size.tiny))
    array.push(labels, label.new(cBar, c, "C", style=label.style_circle, color=color.white, textcolor=color.black, size=size.tiny))
    d_color = isAutoD ? color.purple : color.yellow
    d_text = isAutoD ? "D\n(Auto)" : "D"
    array.push(labels, label.new(dBar, d, d_text, style=label.style_circle, color=d_color, textcolor=color.white, size=size.tiny))

// =========================================
// ORAN ETİKETLERİ
// =========================================
f_draw_ratio_labels(x, a, b, c, d, xBar, aBar, bBar, cBar, dBar) =>
    if show_ratios
        [xab, abc, bcd, xad] = f_calculate_ratios(x, a, b, c, d)
        xab_x = math.round((xBar + bBar) / 2)
        xab_y = (x + b) / 2
        xab_label = label.new(xab_x, xab_y, "XAB\n" + str.tostring(xab, "#.###"), style=label.style_label_center, color=color.new(color.gray, 80), textcolor=color.white, size=size.tiny)
        array.push(labels, xab_label)
        abc_x = math.round((aBar + cBar) / 2)
        abc_y = (a + c) / 2
        abc_label = label.new(abc_x, abc_y, "ABC\n" + str.tostring(abc, "#.###"), style=label.style_label_center, color=color.new(color.gray, 80), textcolor=color.white, size=size.tiny)
        array.push(labels, abc_label)
        bcd_x = math.round((bBar + dBar) / 2)
        bcd_y = (b + d) / 2
        bcd_label = label.new(bcd_x, bcd_y, "BCD\n" + str.tostring(bcd, "#.###"), style=label.style_label_center, color=color.new(color.gray, 80), textcolor=color.white, size=size.tiny)
        array.push(labels, bcd_label)
        xad_x = math.round((xBar + dBar) / 2)
        xad_y = (x + d) / 2
        xad_label = label.new(xad_x, xad_y, "XAD\n" + str.tostring(xad, "#.###"), style=label.style_label_center, color=color.new(color.gray, 80), textcolor=color.white, size=size.tiny)
        array.push(labels, xad_label)

// =========================================
// ANA MANTIK
// =========================================
if (mode == "Otomatik" or mode == "Her İkisi") and barstate.isconfirmed
    f_clear_auto()
    array.clear(autoPatterns)
    f_find_auto_patterns()
    n = array.size(autoPatterns)
    if n > 1
        for i = 0 to n - 2
            for j = 0 to n - i - 2
                if array.get(autoPatterns, j).score < array.get(autoPatterns, j + 1).score
                    temp = array.get(autoPatterns, j)
                    array.set(autoPatterns, j, array.get(autoPatterns, j + 1))
                    array.set(autoPatterns, j + 1, temp)
    maxPatterns = math.min(10, array.size(autoPatterns))
    if maxPatterns > 0
        for i = 0 to maxPatterns - 1
            pattern = array.get(autoPatterns, i)
            f_draw_auto_pattern(pattern)

if (mode == "Manuel" or mode == "Her İkisi") and barstate.islast
    if xP > 0 and aP > 0 and bP > 0 and cP > 0
        f_clear_all()
        xPoint = userPoint.new(xP, xT, na)
        aPoint = userPoint.new(aP, aT, na)
        bPoint = userPoint.new(bP, bT, na)
        cPoint = userPoint.new(cP, cT, na)
        points = array.new<userPoint>(0)
        array.push(points, xPoint)
        array.push(points, aPoint)
        array.push(points, bPoint)
        array.push(points, cPoint)
        userPoint dPoint = na
        if dP > 0 and use_manual_d
            dPoint := userPoint.new(dP, dT, na)
            array.push(points, dPoint)
        f_resolveBarIndex(points)
        isAutoD = not use_manual_d or dP == 0
        float finalD = dP
        int dBar = na
        predictions = f_calculate_multiple_d_predictions(xP, aP, bP, cP)
        if isAutoD
            if array.size(predictions) > 0
                best_pred = array.get(predictions, 0)
                finalD := best_pred.d_price
                dBar := cPoint.bar + 20
                if not na(cPoint.bar) and not use_manual_d
                    f_draw_multiple_d_zones(predictions, cPoint.bar, cP)
            else
                xa = math.abs(aP - xP)
                trend_up = aP > xP
                finalD := trend_up ? aP - xa * 0.786 : aP + xa * 0.786
                dBar := cPoint.bar + 20
        else
            if not na(dPoint) and dP > 0
                dBar := dPoint.bar
                finalD := dP
        if not na(xPoint.bar) and not na(aPoint.bar) and not na(bPoint.bar) and not na(cPoint.bar) and not na(dBar)
            f_draw_pattern(xP, aP, bP, cP, finalD, xPoint.bar, aPoint.bar, bPoint.bar, cPoint.bar, dBar, isAutoD)
            f_draw_ratio_labels(xP, aP, bP, cP, finalD, xPoint.bar, aPoint.bar, bPoint.bar, cPoint.bar, dBar)

if show_pattern_info and barstate.islast
    table.clear(infoTable, 0, 0, 1, 15)
    table.cell(infoTable, 0, 0, "Harmonik Analiz", bgcolor=color.new(color.blue, 50), text_color=color.white)
    table.cell(infoTable, 1, 0, mode, bgcolor=color.new(color.blue, 50), text_color=color.white)
    if mode == "Otomatik" or mode == "Her İkisi"
        table.cell(infoTable, 0, 1, "Bulunan Desenler", bgcolor=color.new(color.gray, 80), text_color=color.white)
        table.cell(infoTable, 1, 1, str.tostring(array.size(autoPatterns)), bgcolor=color.new(color.gray, 80), text_color=color.white)
        if array.size(autoPatterns) > 0
            table.cell(infoTable, 0, 2, "Desen", text_color=color.white)
            table.cell(infoTable, 1, 2, "Skor %", text_color=color.white)
            maxShow = math.min(10, array.size(autoPatterns))
            for i = 0 to maxShow - 1
                if i < array.size(autoPatterns)
                    pattern = array.get(autoPatterns, i)
                    row = 3 + i
                    dirSymbol = pattern.isBullish ? "↑" : "↓"
                    statusText = pattern.isComplete ? "" : " (P)"
                    table.cell(infoTable, 0, row, dirSymbol + " " + pattern.patternType + statusText, text_color=pattern.isBullish ? color.green : color.red)
                    table.cell(infoTable, 1, row, str.tostring(pattern.score, "#.#"), text_color=color.white)
        else
            table.cell(infoTable, 0, 2, "Desen bulunamadı", text_color=color.orange)
            table.cell(infoTable, 1, 2, "-", text_color=color.orange)
    if mode == "Manuel" or mode == "Her İkisi"
        startRow = mode == "Her İkisi" ? 14 : 1
        if xP > 0 and aP > 0 and bP > 0 and cP > 0
            xa = math.abs(aP - xP)
            ab = math.abs(bP - aP)
            bc = math.abs(cP - bP)
            xab = xa != 0 ? ab / xa : 0
            abc = ab != 0 ? bc / ab : 0
            table.cell(infoTable, 0, startRow, "Manuel Oranlar", bgcolor=color.new(color.gray, 80), text_color=color.white)
            table.cell(infoTable, 1, startRow, "", bgcolor=color.new(color.gray, 80))
            table.cell(infoTable, 0, startRow + 1, "XAB", text_color=color.white)
            table.cell(infoTable, 1, startRow + 1, str.tostring(xab, "#.###"), text_color=color.yellow)
            table.cell(infoTable, 0, startRow + 2, "ABC", text_color=color.white)
            table.cell(infoTable, 1, startRow + 2, str.tostring(abc, "#.###"), text_color=color.yellow)
            if dP > 0 or not use_manual_d
                predictions = f_calculate_multiple_d_predictions(xP, aP, bP, cP)
                finalD = dP
                if not use_manual_d and array.size(predictions) > 0
                    best_pred = array.get(predictions, 0)
                    finalD := best_pred.d_price
                if finalD > 0
                    cd = math.abs(finalD - cP)
                    ad = math.abs(finalD - aP)
                    bcd = bc != 0 ? cd / bc : 0
                    xad = xa != 0 ? ad / xa : 0
                    table.cell(infoTable, 0, startRow + 3, "BCD", text_color=color.white)
                    table.cell(infoTable, 1, startRow + 3, str.tostring(bcd, "#.###"), text_color=color.yellow)
                    table.cell(infoTable, 0, startRow + 4, "XAD", text_color=color.white)
                    table.cell(infoTable, 1, startRow + 4, str.tostring(xad, "#.###"), text_color=color.yellow)
                    patterns = f_define_patterns()
                    detectedPatterns = array.new<string>()
                    for pattern in patterns
                        xab_valid = xab >= pattern.xab_min * (1 - tolerance) and xab <= pattern.xab_max * (1 + tolerance)
                        abc_valid = abc >= pattern.abc_min * (1 - tolerance) and abc <= pattern.abc_max * (1 + tolerance)
                        bcd_valid = bcd >= pattern.bcd_min * (1 - tolerance) and bcd <= pattern.bcd_max * (1 + tolerance)
                        xad_valid = xad >= pattern.xad_min * (1 - tolerance) and xad <= pattern.xad_max * (1 + tolerance)
                        if xab_valid and abc_valid and bcd_valid and xad_valid
                            array.push(detectedPatterns, pattern.name)
                    if array.size(detectedPatterns) > 0
                        table.cell(infoTable, 0, startRow + 5, "Tespit:", text_color=color.white)
                        detectedText = ""
                        for i = 0 to math.min(array.size(detectedPatterns) - 1, 2)
                            if i > 0
                                detectedText += ", "
                            detectedText += array.get(detectedPatterns, i)
                        table.cell(infoTable, 1, startRow + 5, detectedText, text_color=color.lime)
        else
            table.cell(infoTable, 0, startRow, "Manuel nokta yok", text_color=color.orange)
            table.cell(infoTable, 1, startRow, "-", text_color=color.orange)

// Uyarılar
if barstate.islast and array.size(autoPatterns) > 0
    for i = 0 to math.min(array.size(autoPatterns) - 1, 5)
        pattern = array.get(autoPatterns, i)
        if pattern.isComplete
            d_distance = math.abs(close - pattern.dPrice)
            d_percent = d_distance / pattern.dPrice * 100
            if d_percent < 1.0
                alert_message = (pattern.isBullish ? "BOĞA " : "AYI ") + pattern.patternType + " deseni D noktasına yakın! Fiyat: " + str.tostring(close)
                alert(alert_message, alert.freq_once_per_bar)

Overview

In automatic mode it scans pivots over a lookback window and scores each match against a minimum percentage; in manual mode the user picks the X, A, B, C and D points. It can draw projected D target zones with Fibonacci ratios, ratio labels and an information table, and raise alerts near point D.

Details

Published by

ggne on GitHub

Type

Indicator, Pine Script v5

Draws

On the price chart

Category

Support & resistance

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

  • Signals can change on the live bar or after it closes (repainting)

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Çalışma ModustringOtomatikmode
Xprice0xP
xTtime0xT
Aprice0aP
aTtime0aT
Bprice0bP
bTtime0bT
Cprice0cP
cTtime0cT
Dprice0dP
dTtime0dT
Geriye Bakış Periyoduint100auto_lookback
Show all 29 settings
SettingTypeDefaultVariable
Minimum Skor %float60.0auto_min_score
Potansiyel Desenleri Gösterbooltrueauto_show_potential
Pivot Uzunluğuint5pivot_length
D Noktasını Manuel Kullanboolfalseuse_manual_d
Tüm D Tahminlerini Gösterbooltrueshow_all_d_predictions
Minimum Güven Skoru %float50.0min_confidence
D Hedef Bölgesini Gösterbooltrueshow_d_zone
C'den D'ye İzdüşüm Çizgileribooltrueshow_projections
Harmonik Oranları Gösterbooltrueshow_ratios
Desen Bilgi Tablosunu Gösterbooltrueshow_pattern_info
En İyi D Tahminini Vurgulabooltruehighlight_best_d
Desen Toleransıfloat0.15tolerance
İzin verilen bacak uzunluğu asimetrisi %float250.0pctAsym
Manuel Boğa Rengicolorcolor.new(color.green, 20)c_bull_manual
Manuel Ayı Rengicolorcolor.new(color.red, 20)c_bear_manual
Otomatik Boğa Rengicolorcolor.new(color.blue, 40)c_bull_auto
Otomatik Ayı Rengicolorcolor.new(color.orange, 40)c_bear_auto
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.

Similar Pine Scripts

948 stars

Moving Average Channel plots separate simple moving averages for upper and lower bands on the price chart. It fills the space between bands with semi-transparent color and colors bars green above the upper band, red below the lower band, or gray in between. Us

Indicator v4 Moving averagesSupport & resistance
Updated 11 days ago · GPL-3.0 GitHub repository of Moving Average Channel

ICT Equal Highs and Lows

by ArunKBhaskar
575 stars

This overlay indicator finds pivot highs and lows on the price chart and compares the last two highs and the last two lows. When the percentage difference between a pair is below the Equal HL threshold, it treats them as equal levels and draws a box. Left and

Indicator v5 SMC / ICT / price actionSupport & resistance
Updated 1 year ago · MPL-2.0 GitHub repository of ICT Equal Highs and Lows
330 stars

This indicator monitors multiple cryptocurrency symbols for trading signals. It calculates and plots entry prices, take profit, and stop loss levels for each symbol including BTCUSDT, ETHUSDT, BNBUSDT and others. Price crossovers trigger buy, sell or close ale

Indicator v5 Support & resistanceScreeners & dashboards
Updated 2 months ago · None stated GitHub repository of Multi Alert Long/Short [Alorse]

This overlay indicator draws a fixed-range volume profile on the price chart, splitting traded activity into up and down volume at each price level. It also plots a sentiment profile, a developing point of control, and value-area high and low around a configur

Indicator v5 VolumeSupport & resistance
Updated 2 months ago · MIT GitHub repository of Volume Profile and Indicator by DGT

BZ-tracker

by Allen1212
303 stars

The BZ-tracker indicator marks ARK Invest buy and sell transactions on stock charts with labels. It plots green labels for purchases and red labels for sales, each annotated with a multiplier such as X1 or X2 to show the number of ARK ETFs trading the stock on

Indicator v4 Support & resistanceScreeners & dashboards
Updated 2 years ago · None stated GitHub repository of BZ-tracker

Function - Linear Regression

by ricardosantos79
261 stars

This indicator fits a linear regression through stored pivot highs and lows and draws the resulting channel on the price chart. A function returns predicted values, maximum and minimum deviations, and the average absolute deviation. Confirmed two-bar pivots up

Indicator v5 TrendSupport & resistance
Updated 4 years ago · None stated GitHub repository of Function - Linear Regression

More indicators

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers