// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © SC97880021 //@version=5 indicator("AI TRENDLINES WITH SWING HIGH LOW", overlay=true, max_lines_count=500, max_bars_back=5000) len = input.int (5 , "Period  " , tooltip = "Lookback period", inline = "a", group = "SETTINGS") cup = input.color(#0044ff, "" , "" , inline = "a", group = "SETTINGS") cdn = input.color(#ff2b00, "" , "" , inline = "a", group = "SETTINGS") space = input.float(2 , "Padding" , tooltip = "Padding distance", inline = "b", group = "SETTINGS", step = 0.1) shs = input.bool (true , "Show Breakouts", inline = "z", group = "SETTINGS") phZ = ta.pivothigh(high, len, len) plZ = ta.pivotlow (low , len, len) type store float src int n type bar float o = open float h = high float l = low float c = close int n = bar_index float v = volume type draw line[] upln line[] dnln var store[] upbin = array.new() var store[] dnbin = array.new() var draw d = draw.new(array.new(), array.new()) bar b = bar.new() atr = ta.atr(200) method slope(line ln) => x = ln.get_x2() - ln.get_x1() y = ln.get_y2() - ln.get_y1() y / x vol() => math.min(atr * 0.1, close * (0.1/100)) var bool broken = false color active = na bool plup = false bool pldn = false if phZ bool remove = false var bool valid = false upbin.unshift(store.new(b.h[len], b.n[len])) if upbin.size() > 1 current = upbin.get(0) before = upbin.get(1) if current.src < before.src if broken valid := true else valid := false if upbin.size() > 3 pastold = upbin.get(3) pastcur = upbin.get(2) now = upbin.get(1) late = upbin.get(0) if now.src < pastcur.src and now.src < pastold.src and late.src < pastcur.src and late.src < pastold.src valid := true else valid := false else valid := false if valid d.upln.unshift(line.new(x1 = before.n, x2 = current.n, y1 = before.src , y2 = current.src , color = cdn)) d.upln.unshift(line.new(x1 = before.n, x2 = current.n, y1 = before.src - vol() * space, y2 = current.src - vol() * space, color = cdn)) ln = d.upln.get(1) for i = 0 to (b.n - before.n) slope = ln.slope() ln.set_x2(b.n[i]) ln.set_y2(ln.get_y2() - slope) if low[i] > ln.get_y2() remove := true break if remove d.upln.get(0).delete() d.upln.get(1).delete() d.upln .clear() upbin .clear() broken := true else d.upln.get(0).delete() d.upln.get(1).delete() d.upln .clear () d.upln.unshift(line.new(x1 = before.n, x2 = current.n, y1 = before.src , y2 = current.src , color = cdn)) d.upln.unshift(line.new(x1 = before.n, x2 = current.n, y1 = before.src - vol() * space, y2 = current.src - vol() * space, color = cdn)) linefill.new(d.upln.get(0), d.upln.get(1), color = color.new(cdn, 75)) upbin.clear() broken := false if d.upln.size() > 1 btm = d.upln.get(0) top = d.upln.get(1) if b.l > top.get_y2() d.upln.clear() broken := true upbin.clear() plup := true if d.upln.size() > 1 slup = top.slope() sldn = btm.slope() top.set_x2(b.n) top.set_y2(top.get_y2() + slup) btm.set_x2(b.n) btm.set_y2(btm.get_y2() + sldn) if plZ bool remove = false var bool valid = false dnbin.unshift(store.new(b.l[len], b.n[len])) if dnbin.size() > 1 current = dnbin.get(0) before = dnbin.get(1) if current.src > before.src if broken valid := true else valid := false if dnbin.size() > 3 pastold = dnbin.get(3) pastcur = dnbin.get(2) now = dnbin.get(1) late = dnbin.get(0) if now.src > pastcur.src and now.src > pastold.src and late.src > pastcur.src and late.src > pastold.src valid := true else valid := false else valid := false if valid d.dnln.unshift(line.new(x1 = before.n, x2 = current.n, y1 = before.src , y2 = current.src , color = cup)) d.dnln.unshift(line.new(x1 = before.n, x2 = current.n, y1 = before.src + vol() * space, y2 = current.src + vol() * space, color = cup)) ln = d.dnln.get(1) for i = 0 to (b.n - before.n) slope = ln.slope() ln.set_x2(b.n[i]) ln.set_y2(ln.get_y2() - slope) if high[i] < ln.get_y2() remove := true break if remove d.dnln.get(0).delete() d.dnln.get(1).delete() d.dnln .clear () dnbin .clear () broken := true else d.dnln.get(0).delete() d.dnln.get(1).delete() d.dnln .clear () d.dnln.unshift(line.new(x1 = before.n, x2 = current.n, y1 = before.src, y2 = current.src, color = cup)) d.dnln.unshift(line.new(x1 = before.n, x2 = current.n, y1 = before.src + vol() * space, y2 = current.src + vol() * space, color = cup)) linefill.new(d.dnln.get(0), d.dnln.get(1), color = color.new(cup, 75)) dnbin.clear() broken := false if d.dnln.size() > 1 btm = d.dnln.get(0) top = d.dnln.get(1) if b.h < btm.get_y2() d.dnln.clear() broken := true dnbin.clear() pldn := true if d.dnln.size() > 1 slup = top.slope() sldn = btm.slope() top.set_x2(b.n) top.set_y2(top.get_y2() + slup) btm.set_x2(b.n) btm.set_y2(btm.get_y2() + sldn) plotshape(pldn and shs ? b.h[1] : na, "Breaking Down", shape.triangledown, location = location.abovebar, color = cdn , offset = -1, size = size.small) plotshape(plup and shs ? b.l[1] : na, "Breaking Up" , shape.triangleup , location = location.belowbar, color = cup, offset = -1, size = size.small) //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // ― SETTINGS lenS = input.int(5, "Pivot Lookback", group="SETTINGS", inline="a") spaceX = input.float(1.0, "Padding", step=0.1, group="SETTINGS", inline="b") cupX = input.color(color.rgb(0, 255, 47), "", inline="c", group="SETTINGS") cdnX = input.color(#ee00ff, "", inline="c", group="SETTINGS") max_span = 500 // Maximum number of future bars allowed // ― Helper Functions vol_pad() => math.min(ta.atr(200) * 0.1, close * 0.001) slope(ln) => (ln.get_y2() - ln.get_y1()) / math.max(ln.get_x2() - ln.get_x1(), 1) // ― Containers var line bull_top = na var line bull_base = na var line bear_top = na var line bear_base = na var bool brokenX = false var bool plupX = false var bool pldnX = false // ― Local TF Pivot High/Low ph = ta.pivothigh(high, lenS, lenS) pl = ta.pivotlow(low, lenS, lenS) // ― Bullish Zone Setup if ph bull_top := line.new(x1=bar_index - lenS, x2=bar_index, y1=high[lenS], y2=high[lenS], color=cupX, width=1) bull_base := line.new(x1=bar_index - lenS, x2=bar_index, y1=high[lenS] - vol_pad() * spaceX, y2=high[lenS] - vol_pad() * spaceX, color=cupX, width=1) linefill.new(bull_top, bull_base, color=color.new(cupX, 85)) brokenX := false // ― Bearish Zone Setup if pl bear_base := line.new(x1=bar_index - lenS, x2=bar_index, y1=low[lenS], y2=low[lenS], color=cdnX, width=1) bear_top := line.new(x1=bar_index - lenS, x2=bar_index, y1=low[lenS] + vol_pad() * spaceX, y2=low[lenS] + vol_pad() * spaceX, color=cdnX, width=1) linefill.new(bear_base, bear_top, color=color.new(cdnX, 85)) brokenX := false // ― Extension Logic if not na(bull_top) and not na(bull_base) sl_top = slope(bull_top) sl_base = slope(bull_base) bull_top.set_x2(bar_index) bull_top.set_y2(bull_top.get_y1() + sl_top * (bar_index - bull_top.get_x1())) bull_base.set_x2(bar_index) bull_base.set_y2(bull_base.get_y1() + sl_base * (bar_index - bull_base.get_x1())) plupX := low > bull_top.get_y2() if not na(bear_top) and not na(bear_base) sl_top = slope(bear_top) sl_base = slope(bear_base) bear_top.set_x2(bar_index) bear_top.set_y2(bear_top.get_y1() + sl_top * (bar_index - bear_top.get_x1())) bear_base.set_x2(bar_index) bear_base.set_y2(bear_base.get_y1() + sl_base * (bar_index - bear_base.get_x1())) pldnX := high < bear_base.get_y2() // ========================================================================================== // === Dashboard with Telegram Link === var table myTable = table.new(position.top_center, 1, 1, border_width=1, frame_color=color.black, bgcolor=color.white) // Add Telegram Message to Dashboard table.cell(myTable, 0, 0, "Join Telegram @mrexpert_ai", bgcolor=color.blue, text_color=color.white, text_size=size.normal)