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

//@version=5
indicator(title="Gap Zones", shorttitle="GZ", overlay=true, max_boxes_count=500, max_labels_count=500, max_lines_count=500)

// <inputs>
i_maxZones = input.int(title='Max Zones', defval=10, maxval=50, minval=1)
i_zoneColor = input.color(title='Zone', defval=color.gray, group='Style')
i_timeframe = input.timeframe(title='Timeframe', defval='', inline='Timeframe', group='Timeframe')
i_timeframeGapsOn = input.bool(title='Timeframe Gaps?', defval=false, inline='Timeframe', group='Timeframe')
// </inputs>

// <funcs>
f_renderGaps() =>
    i_timeframeGapsOn ? barmerge.gaps_on : barmerge.gaps_off

f_regSec(f) =>
    request.security(syminfo.tickerid, i_timeframe, f, f_renderGaps(), barmerge.lookahead_on)

f_isNewTimeframeBar(res) =>
    t = time(res)
    not na(t) and (na(t[1]) or t > t[1])
// </funcs>

// <vars>
var v_boxes = array.new_box(0)
var v_topLines = array.new_line(0)
var v_midLines = array.new_line(0)
var v_bottomLines = array.new_line(0)
var v_labels = array.new_label(0)
v_box_a = 0.0
v_box_b = 0.0

if f_isNewTimeframeBar(i_timeframe)
    v_box_a := f_regSec(close[1])
    v_box_b := f_regSec(open)
    v_range = v_box_a > v_box_b ? v_box_a - v_box_b : v_box_b - v_box_a
    v_mid = v_box_a > v_box_b ? v_box_a - (v_range / 2) : v_box_b - (v_range / 2)
    v_boxes_size = array.size(v_boxes)
 
    if v_boxes_size == i_maxZones
        box.delete(array.remove(v_boxes, 0))
        label.delete(array.remove(v_labels, 0))
        line.delete(array.remove(v_topLines, 0))
        line.delete(array.remove(v_midLines, 0))
        line.delete(array.remove(v_bottomLines, 0))

    array.push(v_boxes, box.new(bar_index, v_box_a, bar_index + 1, v_box_b, border_color = color.new(color.white,100), bgcolor = color.new(i_zoneColor, 90), extend = extend.right))
    array.push(v_labels, label.new(bar_index + 20, v_mid, text = str.tostring(i_timeframe) + " Zone", style=label.style_text_outline, size = size.normal, textcolor = color.white, color=color.black))
    array.push(v_topLines, line.new(bar_index, v_box_a, bar_index + 1, v_box_a, extend=extend.right, color=i_zoneColor))
    array.push(v_midLines, line.new(bar_index, v_mid, bar_index + 1, v_mid, extend=extend.right, color=color.new(i_zoneColor, 50), style=line.style_dashed))
    array.push(v_bottomLines, line.new(bar_index, v_box_b, bar_index + 1, v_box_b, extend=extend.right, color=i_zoneColor))
// </vars>