//@version=6
indicator("İkili Dip Tespiti ", overlay=true, max_lines_count=500, max_labels_count=500)
// === INPUTS ===
tolerancePercent = input.float(0.5, "Dip Seviye Toleransı (%)") / 100
minBarsBetween = input.int(5, "İki Dip Arası Min Bar", minval=2)
maxBarsBetween = input.int(200, "İki Dip Arası Maks Bar")
lookbackBars = input.int(200, "Aranacak Maks Bar Sayısı")
leftLookback = input.int(50, "Sol En Yüksek Bakış Mesafesi", minval=10)
rightLookback = input.int(50, "Sağ En Yüksek Bakış Mesafesi", minval=10)
tpMultiplier = input.float(2.0, "Temel TP Çarpanı (x)", step=0.1, minval=0.5)
showMultipleTP = input.bool(true, "Farklı TP Katlarını Göster (1.5x, 2x, 2.5x)")
// Swing low tespiti
isSwingLow = low[2] < low[1] and low[2] < low[3] and low[2] < low[0] and low[2] < low[4]
// Son iki swing low
var float lastSwingLow = na
var int lastSwingLowBar = na
var float secondLastSwingLow = na
var int secondLastSwingLowBar = na
if isSwingLow
secondLastSwingLow := lastSwingLow
secondLastSwingLowBar := lastSwingLowBar
lastSwingLow := low[2]
lastSwingLowBar := bar_index[2]
// Array'ler
var array<line> allLines = array.new<line>()
var array<label> allLabels = array.new<label>()
// Son kırılma takibi (label'ların sadece bir kez çıkması için)
var int lastBreakoutBar = -1
// Güvenli temizleme
clearDrawings() =>
if array.size(allLines) > 0
for i = 0 to array.size(allLines) - 1
line.delete(array.get(allLines, i))
array.clear(allLines)
if array.size(allLabels) > 0
for i = 0 to array.size(allLabels) - 1
label.delete(array.get(allLabels, i))
array.clear(allLabels)
// İkili dip kontrolü
if not na(secondLastSwingLow) and not na(lastSwingLow)
int barFarki = math.abs(lastSwingLowBar - secondLastSwingLowBar)
float farkOrani = math.abs(lastSwingLow - secondLastSwingLow) / secondLastSwingLow
bool mesafeUygun = barFarki >= minBarsBetween and barFarki <= maxBarsBetween and barFarki <= lookbackBars
bool seviyeUygun = farkOrani <= tolerancePercent
if mesafeUygun and seviyeUygun
int leftBar = math.min(secondLastSwingLowBar, lastSwingLowBar)
int rightBar = math.max(secondLastSwingLowBar, lastSwingLowBar)
float boyunCizgisi = na
int enYuksekBarIndex = na
if rightBar - leftBar <= 500
float maxHigh = -1e10
for i = leftBar to rightBar
int offset = bar_index - i
if offset >= 0 and high[offset] > maxHigh
maxHigh := high[offset]
enYuksekBarIndex := i
boyunCizgisi := maxHigh
if not na(boyunCizgisi) and not na(enYuksekBarIndex)
// Önceki tüm çizimleri temizle (sadece en son ikili dip kalır)
clearDrawings()
// === Yapısal Çizgiler ===
line.new(secondLastSwingLowBar, secondLastSwingLow, enYuksekBarIndex, boyunCizgisi, color=color.yellow, width=3)
line.new(lastSwingLowBar, lastSwingLow, enYuksekBarIndex, boyunCizgisi, color=color.yellow, width=3)
// Boyun çizgisi (sağa uzat)
boyunLine = line.new(enYuksekBarIndex, boyunCizgisi, bar_index + 100, boyunCizgisi,
color=color.new(color.black, 0), style=line.style_dotted, width=2, extend=extend.right)
array.push(allLines, boyunLine)
// Sol ve Sağ en yüksek
float leftMaxHigh = -1e10
int leftMaxBar = na
for i = math.max(0, secondLastSwingLowBar - leftLookback) to secondLastSwingLowBar
int offset = bar_index - i
if high[offset] > leftMaxHigh
leftMaxHigh := high[offset]
leftMaxBar := i
if not na(leftMaxBar) and leftMaxBar < secondLastSwingLowBar
lineSol = line.new(leftMaxBar, leftMaxHigh, secondLastSwingLowBar, secondLastSwingLow, color=color.new(color.blue, 20), width=3)
array.push(allLines, lineSol)
float rightMaxHigh = -1e10
int rightMaxBar = na
for i = lastSwingLowBar to math.min(bar_index, lastSwingLowBar + rightLookback)
int offset = bar_index - i
if offset >= 0 and high[offset] > rightMaxHigh
rightMaxHigh := high[offset]
rightMaxBar := i
if not na(rightMaxBar) and rightMaxBar > lastSwingLowBar
lineSag = line.new(lastSwingLowBar, lastSwingLow, rightMaxBar, rightMaxHigh, color=color.new(color.blue, 20), width=3)
array.push(allLines, lineSag)
// === Kırılma Kontrolü ===
bool breakout = close > boyunCizgisi and barstate.isconfirmed
if breakout and lastBreakoutBar != lastSwingLowBar
lastBreakoutBar := lastSwingLowBar
// Temel label'lar
labelDip1 = label.new(secondLastSwingLowBar, secondLastSwingLow, "Dip 1", color=color.new(color.orange, 80), textcolor=color.white, style=label.style_label_up, size=size.tiny)
labelDip2 = label.new(lastSwingLowBar, lastSwingLow, "Dip 2", color=color.new(color.orange, 80), textcolor=color.white, style=label.style_label_up, size=size.tiny)
labelBoyun = label.new(enYuksekBarIndex, boyunCizgisi, "Boyun", color=color.new(color.blue, 80), textcolor=color.white, style=label.style_label_down, size=size.tiny)
array.push(allLabels, labelDip1)
array.push(allLabels, labelDip2)
array.push(allLabels, labelBoyun)
// Ana sinyal
signalLabel = label.new(lastSwingLowBar, lastSwingLow - ta.tr * 2,
"✓ İKİLİ DİP\nBoyun: " + str.tostring(boyunCizgisi, "#.####"),
color=color.new(color.green, 80), textcolor=color.white, style=label.style_label_up, size=size.small)
array.push(allLabels, signalLabel)
// === TP Çizgileri + DETAYLI LABEL'LAR (SAĞA UZATILMIŞ) ===
float height = boyunCizgisi - lastSwingLow
// Temel TP
float tpBase = lastSwingLow + height * tpMultiplier
tpBaseLine = line.new(lastSwingLowBar, tpBase, bar_index + 100, tpBase,
color=color.fuchsia, style=line.style_dotted, width=2, extend=extend.right)
array.push(allLines, tpBaseLine)
tpBaseLabel = label.new(lastSwingLowBar, tpBase + ta.tr * 0.0,
"TP " + str.tostring(tpMultiplier, "0.0") + "x - " + str.tostring(tpBase, "#.####"),
color=color.new(color.fuchsia, 70), textcolor=color.white, style=label.style_label_right, size=size.normal)
array.push(allLabels, tpBaseLabel)
if showMultipleTP
// 1.5x
float tp15 = lastSwingLow + height * (tpMultiplier * 1.5)
tp15Line = line.new(lastSwingLowBar, tp15, bar_index + 100, tp15, color=color.purple, style=line.style_dotted, width=2, extend=extend.right)
array.push(allLines, tp15Line)
tp15Label = label.new(lastSwingLowBar + 4, tp15 + ta.tr * 0.0,
"TP " + str.tostring(tpMultiplier * 1.5, "0.0") + "x - " + str.tostring(tp15, "#.####"),
color=color.new(color.purple, 70), textcolor=color.white, style=label.style_label_right, size=size.small)
array.push(allLabels, tp15Label)
// 2.0x
float tp20 = lastSwingLow + height * (tpMultiplier * 2.0)
tp20Line = line.new(lastSwingLowBar, tp20, bar_index + 100, tp20, color=color.red, style=line.style_dotted, width=2, extend=extend.right)
array.push(allLines, tp20Line)
tp20Label = label.new(lastSwingLowBar + 8, tp20 + ta.tr * 0.0,
"TP " + str.tostring(tpMultiplier * 2.0, "0.0") + "x - " + str.tostring(tp20, "#.####"),
color=color.new(color.red, 70), textcolor=color.white, style=label.style_label_right, size=size.small)
array.push(allLabels, tp20Label)
// 2.5x
float tp25 = lastSwingLow + height * (tpMultiplier * 2.5)
tp25Line = line.new(lastSwingLowBar, tp25, bar_index + 100, tp25, color=color.maroon, style=line.style_dotted, width=2, extend=extend.right)
array.push(allLines, tp25Line)
tp25Label = label.new(lastSwingLowBar + 12, tp25 + ta.tr * 0.0,
"TP " + str.tostring(tpMultiplier * 2.5, "0.0") + "x - " + str.tostring(tp25, "#.####"),
color=color.new(color.maroon, 70), textcolor=color.white, style=label.style_label_right, size=size.small)
array.push(allLabels, tp25Label)
alert("İkili Dip + Kırılım! Boyun: " + str.tostring(boyunCizgisi, "#.####") +
" | TP: " + str.tostring(tpBase, "#.####"), alert.freq_once_per_bar)
// Swing low gösterimi
//plotshape(isSwingLow, "Swing Low", shape.triangleup, location.belowbar, color.new(color.purple, 40), size=size.small)
// Durum tablosu
var table statusTable = table.new(position.top_right, 2, 5, bgcolor=color.new(color.black, 85))
if barstate.islast
table.cell(statusTable, 0, 0, "Son Dip Farkı:", text_color=color.white)
table.cell(statusTable, 1, 0, not na(secondLastSwingLow) ? str.tostring(math.abs(lastSwingLow - secondLastSwingLow) / secondLastSwingLow * 100, "#.##") + "%" : "-", text_color=color.yellow)
table.cell(statusTable, 0, 1, "Bar Aralığı:", text_color=color.white)
table.cell(statusTable, 1, 1, not na(secondLastSwingLow) ? str.tostring(math.abs(lastSwingLowBar - secondLastSwingLowBar)) : "-", text_color=color.yellow)
table.cell(statusTable, 0, 2, "Temel TP:", text_color=color.white)
table.cell(statusTable, 1, 2, str.tostring(tpMultiplier, "0.0") + "x", text_color=color.fuchsia)
table.cell(statusTable, 0, 3, "Durum:", text_color=color.white)
table.cell(statusTable, 1, 3, not na(secondLastSwingLow) ? "İkili Dip Bekleniyor" : "Dip 1 Bekleniyor", text_color=color.orange)
Swing Low tespiti yapar (bir önceki ve sonraki 2 bardan düşük olan dipler)
Arka arkaya iki swing low bulur ve:
Farkları tolerans içinde mi?
Bar aralığı uygun mu?
Boyun çizgisini (iki dip arasındaki en yüksek tepe) çizer
Kırılım olduğunda (kapanış boyun çizgisini geçerse):
✅ “İKİLİ DİP” sinyali verir
📈 TP (Take Profit) seviyelerini çizer
🔔 Alert oluşturur
Renk/Görsel
Anlamı
🟡 Sarı çizgiler
Dipleri boyun çizgisine bağlayan yapısal çizgiler
🔵 Mavi çizgiler
Sol ve sağ en yüksek seviyeleri gösteren yardımcı çizgiler
⚫ Siyah noktalı çizgi
Boyun çizgisi (kırılma seviyesi)
🟣 Mor/Eflatun
TP seviyeleri (kâr hedefi çizgileri)
🟢 Yeşil etiket
“İKİLİ DİP” sinyali ve boyun seviyesi
🟠 Turuncu etiket
“Dip 1” ve “Dip 2” işaretleri
Sinyali bekleyin: Yeşil “İKİLİ DİP” etiketi ve kırılım çizgisi göründüğünde
Giriş: Boyun çizgisi kırıldıktan sonra (genellikle bir sonraki mumda)
Stop Loss: İkinci dip seviyesinin hemen altına konulabilir
Take Profit:
TP 1.5x / 2x / 2.5x: Kademeli kâr alma için
En az TP 2x hedeflenebilir