ZigZag++ Fibonacci
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © DevLucem
//  (                   (                            
//  )\ )                )\ )                         
// (()/(     (    )    (()/(   (          (     )    
//  /(_))   ))\  /((    /(_)) ))\   (    ))\   (     
// (_))_   /((_)(_))\  (_))  /((_)  )\  /((_)  )\  ' 
//  |   \ (_))  _)((_) | |  (_))(  ((_)(_))  _((_))  
//  | |) |/ -_) \ V /  | |__| || |/ _| / -_)| '  \() 
//  |___/ \___|  \_/   |____|\_,_|\__| \___||_|_|_| 
import DevLucem/ZigLib/1 as ZigZag

//@version=5
indicator("ZigZag++ Fibonacci", "ZigFib", true)

resolution = input.timeframe("")
_high = input.source(high, "High", inline="source")
_low = input.source(low, "Low", inline="source")

depth = input.int(12)
deviation = input.int(5)
backstep = input.int(2)

[direction, z1, z2] = request.security(syminfo.tickerid, resolution, ZigZag.zigzag(_low, _high, depth, deviation, backstep))

mode = input.string('Retracements','Fibonacci',options=['Retracements', 'Timezone'])

fib = array.new_float(0)
fib_col = array.new_color(0)

fib_0_lvl = input(0,'',inline='inline0',group='Fibonacci')
fib_0_col = input(#21f321,'',inline='inline0',group='Fibonacci')
if input(false,'Fib 0',inline='inline0',group='Fibonacci')
    array.push(fib, fib_0_lvl)
    array.push(fib_col, fib_0_col)

fib_a_lvl = input(0.236,'',inline='inline1',group='Fibonacci')
fib_a_col = input(#21c6f3,'',inline='inline1',group='Fibonacci')
if input(false,'Fib A',inline='inline1',group='Fibonacci')
    array.push(fib, fib_a_lvl)
    array.push(fib_col, fib_a_col)

fib_b_lvl = input(0.382,'',inline='inline2',group='Fibonacci')
fib_b_col = input(#0cb51a,'',inline='inline2',group='Fibonacci')
if input(false,'Fib B',inline='inline2',group='Fibonacci')
    array.push(fib,fib_b_lvl)
    array.push(fib_col,fib_b_col)

fib_c_lvl = input(0.5,'',inline='inline3',group='Fibonacci')
fib_c_col = input(#ff5d00,'',inline='inline3',group='Fibonacci')
if input(true,'Fib C',inline='inline3',group='Fibonacci')
    array.push(fib,fib_c_lvl)
    array.push(fib_col,fib_c_col)

fib_d_lvl = input(0.618,'',inline='inline4',group='Fibonacci')
fib_d_col = input(#64b5f6,'',inline='inline4',group='Fibonacci')
if input(false,'Fib D',inline='inline4',group='Fibonacci')
    array.push(fib,fib_d_lvl)
    array.push(fib_col,fib_d_col)

fib_e_lvl = input(0.786,'',inline='inline5',group='Fibonacci')
fib_e_col = input(#673ab7,'',inline='inline5',group='Fibonacci')
if input(false,'Fib E',inline='inline5',group='Fibonacci')
    array.push(fib,fib_e_lvl)
    array.push(fib_col,fib_e_col)

fib_f_lvl = input(1.,'',inline='inline6',group='Fibonacci')
fib_f_col = input(#e91e63,'',inline='inline6',group='Fibonacci')
if input(true,'Fib F',inline='inline6',group='Fibonacci')
    array.push(fib,fib_f_lvl)
    array.push(fib_col,fib_f_col)

drawFib(x1, y1, x2, y2) =>
    lines = array.new_line(na)
    labels = array.new_label(na)

    sum = 0, a = 0, b = 0

    for i = 0 to array.size(fib)-1
        if mode == 'Retracements'
            lvl = y2 + array.get(fib, i)*(y1-y2)
            array.push(lines, line.new(x1, lvl, x2, lvl, xloc.bar_time, color=array.get(fib_col, i)))
            array.push(labels, label.new(x1, lvl, str.tostring(array.get(fib,i)), xloc.bar_time, yloc.price, #00000000, label.style_label_right, array.get(fib_col,i), size.small, text.align_center))

        if mode == 'Timezone'
            array.push(lines, line.new(x1 + (x2-x1)*sum, high, x1 + (x2-x1)*sum, low, xloc.bar_time, extend=extend.both, color=array.get(fib_col,i)))
            sum := a + b
            a := b, b := sum

    [lines, labels]
        

bgcolor(color.new(direction<0? fib_f_col: fib_a_col, 80))

line zigzag = line.new(z1.time, z1.price, z2.time, z2.price, xloc.bar_time, width=3)
[fibs, labels] = drawFib(z1.time, z1.price, z2.time, z2.price)

if direction==direction[1]
    line.delete(zigzag[1])
    for i = 0 to array.size(fibs[1])-1
        line.delete(array.get(fibs[1], i))
        if array.size(labels[1])>i
            label.delete(array.get(labels[1], i))




//  (                   (                            
//  )\ )                )\ )                         
// (()/(     (    )    (()/(   (          (     )    
//  /(_))   ))\  /((    /(_)) ))\   (    ))\   (     
// (_))_   /((_)(_))\  (_))  /((_)  )\  /((_)  )\  ' 
//  |   \ (_))  _)((_) | |  (_))(  ((_)(_))  _((_))  
//  | |) |/ -_) \ V /  | |__| || |/ _| / -_)| '  \() 
//  |___/ \___|  \_/   |____|\_,_|\__| \___||_|_|_| 