Auto Fib Zones
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © melodicfish

//@version=5
indicator("Auto Fib Zones",shorttitle="AFZ", overlay=true,max_bars_back = 250)
t_col=input(color.new(#787b86, 85),title="Trend Line Color",inline="6")
zone1=input(color.rgb(0, 255, 229, 89),title="Zone 1",inline="4")
zone2=input(color.rgb(0, 140, 255, 91),title="Zone 2",inline="4")

barsR=0
barsL=input(50,title="Bars Back",tooltip="Number of bars left of the Pivot")
boxNum=input(5,title="Boxs")

var lastPivotType=0
var phIndex=0
var plIndex=0
var ph=0.0
var pl=0.0
var highp=0.0
var lowp=0.0
var lastLine=line.new(0,0,0,0)
var patTop=0.0
var patBottom=0.0

var l0=line.new(0,0,0,0,extend=extend.right,color=color.rgb(76, 175, 79, 100),width=2)//leading point

var l1=line.new(0,0,0,0,extend=extend.right,color=color.rgb(33, 149, 243, 100),width=2)//leading pl
var l2=line.new(0,0,0,0,extend=extend.right,color=color.rgb(255, 153, 0, 100),width=2)//following

var l3=line.new(0,0,0,0,extend=extend.right,color=color.rgb(223, 64, 251, 100),width=2)//leading ph
var l4=line.new(0,0,0,0,extend=extend.right,color=color.rgb(255, 82, 82, 100),width=2)//following

var leadPointVal=0.0

var lines= array.new_line(5)
array.set(lines,0,l0)
array.set(lines,1,l1)
array.set(lines,2,l2)
array.set(lines,3,l3)
array.set(lines,4,l4)

ph:=ta.pivothigh(high,barsL,barsR)
pl:= ta.pivotlow(low,barsL,barsR)

//Update the holding variables
if ph>0
    highp:=ph
if pl>0
    lowp:=pl
    
// Get the new index
phIndex:=ph?bar_index-barsR:phIndex[1]
plIndex:=pl?bar_index-barsR:plIndex[1]

// Update direction type
lastPivotType:= ph?1:pl?-1:barstate.isfirst?0:lastPivotType[1]

var d_newTrendFormed=0
//create new line set xy2 and get end of previous line NewUT
if lastPivotType!=lastPivotType[1] and lastPivotType==1

    patTop:=high
    patBottom:=line.get_y1(l0)
    line.set_x1(array.get(lines,2),line.get_x2(array.get(lines,1))-1)
    line.set_y1(array.get(lines,2),line.get_y2(array.get(lines,1)))
    line.set_x2(array.get(lines,2),line.get_x2(array.get(lines,1))+1)
    line.set_y2(array.get(lines,2),line.get_y2(array.get(lines,1)))
    
    lastLine:=line.new(line.get_x1(lastLine),line.get_y1(lastLine),phIndex,high[bar_index-phIndex])
   


    line.set_x1(array.get(lines,1),line.get_x1(lastLine))
    line.set_y1(array.get(lines,1),line.get_y1(lastLine))
    line.set_x2(array.get(lines,1),line.get_x1(lastLine)+1)
    line.set_y2(array.get(lines,1),line.get_y1(lastLine))
    line.set_x1(array.get(lines,0),line.get_x2(lastLine))
    line.set_y1(array.get(lines,0),line.get_y2(lastLine))
    line.set_x2(array.get(lines,0),line.get_x2(lastLine)+1)
    line.set_y2(array.get(lines,0),line.get_y2(lastLine))
    line.set_color(lastLine,t_col)
    
    d_newTrendFormed:=1

 //create new line set xy1 and get end of prevous line New DT
if lastPivotType!=lastPivotType[1] and lastPivotType==-1

    patTop:=line.get_y1(l0)
    patBottom:=low
    line.set_x1(array.get(lines,4),line.get_x2(array.get(lines,3))-1)
    line.set_y1(array.get(lines,4),line.get_y2(array.get(lines,3)))
    line.set_x2(array.get(lines,4),line.get_x2(array.get(lines,3))+1)
    line.set_y2(array.get(lines,4),line.get_y2(array.get(lines,3)))

    lastLine:=line.new(plIndex,low[bar_index-plIndex],line.get_x2(lastLine),line.get_y2(lastLine))
    line.set_x1(array.get(lines,0),line.get_x1(lastLine))
    line.set_y1(array.get(lines,0),line.get_y1(lastLine))
    line.set_x2(array.get(lines,0),line.get_x1(lastLine)+1)
    line.set_y2(array.get(lines,0),line.get_y1(lastLine))
    line.set_x1(array.get(lines,3),line.get_x2(lastLine))
    line.set_y1(array.get(lines,3),line.get_y2(lastLine))
    line.set_x2(array.get(lines,3),line.get_x2(lastLine)+1)
    line.set_y2(array.get(lines,3),line.get_y2(lastLine))
    line.set_color(lastLine,t_col)
    d_newTrendFormed:=-1

// Update Trend Down Line  
if lastPivotType==lastPivotType[1] and lastPivotType==-1 and pl<lowp[1]
    line.set_x1(lastLine[1],plIndex)
    line.set_y1(lastLine[1],low[bar_index-plIndex])
    line.set_color(lastLine[1],t_col)
    
    line.set_x1(array.get(lines,0),line.get_x1(lastLine))
    line.set_y1(array.get(lines,0),line.get_y1(lastLine))
    line.set_x2(array.get(lines,0),line.get_x1(lastLine)+1)
    line.set_y2(array.get(lines,0),line.get_y1(lastLine))
    patBottom:=low
    
// Update Trend Up Line 
if lastPivotType==lastPivotType[1] and lastPivotType==1 and ph>highp[1]

    line.set_x2(lastLine[1],phIndex)
    line.set_y2(lastLine[1],high[bar_index-phIndex])
    line.set_color(lastLine[1],t_col)
    
    line.set_x1(array.get(lines,0),line.get_x2(lastLine))
    line.set_y1(array.get(lines,0),line.get_y2(lastLine))
    line.set_x2(array.get(lines,0),line.get_x2(lastLine)+1)
    line.set_y2(array.get(lines,0),line.get_y2(lastLine))
    patTop:=high

//Fibs******** 


var clear_col=color.new(color.white,100)
Fib(ratio) =>
    valueRange= patTop-patBottom
    if d_newTrendFormed==1
        fibVal=patTop-(valueRange*ratio)
    else 
        fibVal=patBottom+(valueRange*ratio)

var fib1=line.new(0,0,0,0,color=color.rgb(76, 175, 79, 100))    
var fib2=line.new(0,0,0,0,color=color.rgb(33, 149, 243, 100))    
var fib3=line.new(0,0,0,0,color=color.rgb(255, 153, 0, 100))  
var fibBase1=line.new(0,0,0,0,color=color.rgb(155, 39, 176, 100))  


fibX=d_newTrendFormed==1?line.get_x1(l1):line.get_x1(l3)
fibY=d_newTrendFormed==1?l1:l3


line.set_xy1(fib1,fibX,Fib(0.786))
line.set_xy2(fib1,fibX+25,Fib(0.786))

line.set_xy1(fib2,fibX,Fib(0.5))
line.set_xy2(fib2,fibX+25,Fib(0.5))

line.set_xy1(fib3,fibX,Fib(0.618))
line.set_xy2(fib3,fibX+25,Fib(0.618))

base=d_newTrendFormed==-1?patTop:patBottom
line.set_xy1(fibBase1,fibX,base)
line.set_xy2(fibBase1,fibX+25,base)

plotchar(patTop,title="Top",char="")
plotchar(patBottom,title="Bottom",char="")


bosLCdOneLookback=bar_index-line.get_x1(array.get(lines,3))
bosLCdOneindex=ta.lowestbars(low,math.max(bosLCdOneLookback,1)) 
bosLCdTwoLookback=bar_index-line.get_x1(array.get(lines,4))
bosLCdTwoindex=ta.lowestbars(low,math.max(bosLCdTwoLookback,1)) 

var boxArrayL=array.new_box()   
var boxArrayTestedL=array.new_bool()   
var boxArrayLz1=array.new_box()   
var boxArrayTestedLz1=array.new_bool()   

if d_newTrendFormed==1 and d_newTrendFormed[1]==-1
    b1=box.new(bosLCdOneindex+bar_index,line.get_y1(fib1),bar_index,low[math.abs(bosLCdOneindex)],bgcolor=zone2,border_color = color.rgb(76, 175, 79, 100))
    b2=box.new(bosLCdOneindex+bar_index,line.get_y1(fib1),bar_index,line.get_y1(fib3),bgcolor=zone1,border_color = color.rgb(76, 175, 79, 100))

    if array.size(boxArrayL)>=boxNum
        box.delete(array.get(boxArrayL,boxNum-1))
        array.pop(boxArrayL)
        array.pop(boxArrayTestedL)
    array.unshift(boxArrayL,b1)
    array.unshift(boxArrayTestedL,false)
    if array.size(boxArrayLz1)>=boxNum
        box.delete(array.get(boxArrayLz1,boxNum-1))
        array.pop(boxArrayLz1)
        array.pop(boxArrayTestedLz1)
    array.unshift(boxArrayLz1,b2)
    array.unshift(boxArrayTestedLz1,false)
if d_newTrendFormed==1 and array.size(boxArrayL)>1 
    if array.get(boxArrayTestedLz1,0)==false
        box.set_top(array.get(boxArrayL,0),line.get_y1(fib1))
        box.set_bottom(array.get(boxArrayLz1,0),box.get_top(array.get(boxArrayL,0)))
        box.set_top(array.get(boxArrayLz1,0),line.get_y1(fib3))
        

// //Short Side
d_boms_S=false
bosSCdOneLookback=bar_index-line.get_x1(array.get(lines,1))
bosSCdOneindex=ta.highestbars(high,math.max(bosSCdOneLookback,1)) 
bosSCdTwoLookback=bar_index-line.get_x1(array.get(lines,2))
bosSCdTwoindex=ta.highestbars(high,math.max(bosSCdTwoLookback,1)) 


var boxArrayS=array.new_box()   
var boxArrayTestedS=array.new_bool()   
var boxArraySz1=array.new_box()   
var boxArrayTestedSz1=array.new_bool()   

if d_newTrendFormed==-1 and d_newTrendFormed[1]==1
    b1=box.new(bosSCdOneindex+bar_index,high[math.abs(bosSCdOneindex)],bar_index,line.get_y1(fib1),bgcolor=zone2,border_color = color.rgb(255, 82, 82, 100))
    b2=box.new(bosSCdOneindex+bar_index,line.get_y1(fib1),bar_index,line.get_y1(fib3),bgcolor=zone1,border_color = color.rgb(255, 82, 82, 100))
    if array.size(boxArrayS)>=boxNum
        box.delete(array.get(boxArrayS,boxNum-1))
        array.pop(boxArrayS)
        array.pop(boxArrayTestedS)
    array.unshift(boxArrayS,b1)
    array.unshift(boxArrayTestedS,false)
    if array.size(boxArraySz1)>=boxNum
        box.delete(array.get(boxArraySz1,boxNum-1))
        array.pop(boxArraySz1)
        array.pop(boxArrayTestedSz1)
    array.unshift(boxArraySz1,b2)
    array.unshift(boxArrayTestedSz1,false)
if d_newTrendFormed==-1 and array.size(boxArrayS)>1 
    if array.get(boxArrayTestedSz1,0)==false
        box.set_bottom(array.get(boxArrayS,0),line.get_y1(fib1))
        box.set_top(array.get(boxArraySz1,0),box.get_bottom(array.get(boxArrayS,0)))
        box.set_bottom(array.get(boxArraySz1,0),line.get_y1(fib3))

//Update L Boxes
if array.size(boxArrayL) > 0 and barstate.isconfirmed
    for i=0 to array.size(boxArrayL)-1
        if low >= box.get_top(array.get(boxArrayL,i)) and array.get(boxArrayTestedL,i)==false
            box.set_right(array.get(boxArrayL,i),bar_index+1)

        else
            array.set(boxArrayTestedL,i,true)

//Update L Boxes
if array.size(boxArrayLz1) > 0 and barstate.isconfirmed
    for i=0 to array.size(boxArrayLz1)-1
        if low >= box.get_top(array.get(boxArrayLz1,i)) and array.get(boxArrayTestedLz1,i)==false
            box.set_right(array.get(boxArrayLz1,i),bar_index+1)

        else
            array.set(boxArrayTestedLz1,i,true)
                    

//Update S Boxes
if array.size(boxArrayS) > 0 and barstate.isconfirmed
    for i=0 to array.size(boxArrayS)-1
        if high <= box.get_bottom(array.get(boxArrayS,i)) and array.get(boxArrayTestedS,i)==false
            box.set_right(array.get(boxArrayS,i),bar_index+1)

        else
            array.set(boxArrayTestedS,i,true)

//Update S Boxes
if array.size(boxArraySz1) > 0 and barstate.isconfirmed
    for i=0 to array.size(boxArraySz1)-1
        if high <= box.get_bottom(array.get(boxArraySz1,i)) and array.get(boxArrayTestedSz1,i)==false
            box.set_right(array.get(boxArraySz1,i),bar_index+1)

        else
            array.set(boxArrayTestedSz1,i,true)

