Bart Pattern [LuxAlgo]
// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// © LuxAlgo

//@version=5
indicator("Bart Pattern Detector [LuxAlgo]",overlay=true,max_boxes_count=500,max_lines_count=500)
length    = input(25,'Median Lookback')
mult      = input(1.,'Edge Detection Sensitivity')
threshold = input(2.,'Range To Edges Threshold')
invert    = input(false,'Show Inverted Barts')

mode     = input.string('Bartify',options=['Simple','Bartify'])
//------------------------------------------------------------------------------
var y = array.new_float(0)
var x = array.new_int(0)
var ds = array.new_float(0)
var os = 0
//------------------------------------------------------------------------------
n = bar_index
src = close
atr = ta.atr(100)*mult

med = ta.percentile_linear_interpolation(src,length,50)
d = med-med[1]

os := d > atr ? 1 : d < -atr ? 0 : os[1]

if d > atr or d < -atr
    array.unshift(ds,math.abs(d))

condition = invert ? os != os[1] : os < os[1]

if condition
    dist = array.range(y)/(array.get(ds,0)+array.get(ds,1))
    
    if dist < threshold
        if (os == 0 and src[length/2] < array.min(y)) or (os == 1 and src[length/2] > array.max(y))
            
            if mode == 'Bartify'
                base = os == 1 ? array.max(y)+array.range(y) : array.min(y)-array.range(y)
                
                prev_x = array.get(x,0)
                prev_y = array.get(y,0)
                
                t = 0
                Y = 0.
                for i = 0 to array.size(x)-1 by math.max(int(array.size(x)/10),1)
                    if os == 1
                        Y := array.min(y) + t%2*array.range(y)
                    else
                        Y := array.max(y) - t%2*array.range(y)
                    
                    l1 = line.new(prev_x,prev_y,array.get(x,i),Y,color=color.black)
                    l2 = line.new(prev_x,base,array.get(x,i),base,color=na)
                    t += 1
                    
                    linefill.new(l1,l2,color=color.yellow)
                    
                    prev_x := array.get(x,i)
                    prev_y := Y
            else
                box.new(array.get(x,0),array.max(y),int(n-length/2),array.min(y)
                  ,border_color= os == 1 ? #0cb51a : #ff1100
                  ,bgcolor=color.new(os == 1 ? #0cb51a : #ff1100,50))
    
if d > atr or d < -atr
    array.clear(y)
    array.clear(x)
    
array.push(y,src[length/2])
array.push(x,n[length/2])

//------------------------------------------------------------------------------
var upper_dash = table.new(position.top_right,1,1)
var lower_dash = table.new(position.bottom_right,1,1)

if mode == 'Bartify'
    if os == 0
        table.cell(upper_dash,0,0,'EAT MY',text_color=color.red,text_size=size.huge,bgcolor=color.new(color.red,50))
        table.cell(lower_dash,0,0,'SHORTS 🩳 !!',text_color=color.red,text_size=size.huge,bgcolor=color.new(color.red,50))
    else
        table.cell(upper_dash,0,0,'EAT MY',text_color=color.green,text_size=size.huge,bgcolor=color.new(color.green,50))
        table.cell(lower_dash,0,0,'LONGS 🌕 !!',text_color=color.green,text_size=size.huge,bgcolor=color.new(color.green,50))
else
    if os == 0
        table.cell(upper_dash,0,0,'Down Trend',text_color=color.red,text_size=size.normal,bgcolor=color.new(color.red,50))
    else
        table.cell(upper_dash,0,0,'Up Trend',text_color=color.green,text_size=size.normal,bgcolor=color.new(color.green,50))
