Opening Range Gaps [TFO]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © tradeforopp

//@version=5
indicator("Opening Range Gaps [TFO]", "Opening Range Gaps [TFO]", true, max_boxes_count = 500, max_lines_count = 500)

var g_SET = "Settings"
session = input.session("1600-0930", "Gap Session", tooltip = "The window of time from which the gap will be derived", group = g_SET)
gap_up_color = input.color(color.new(color.blue, 80), "Gap Colors", inline = "RG", group = g_SET)
gap_dn_color = input.color(color.new(color.red, 80), "", inline = "RG", group = g_SET)
delineations = input.bool(true, "Show Session Delineations", inline = "SD", tooltip = "Vertical lines will mark the gap session start and end times", group = g_SET)
del_color = input.color(color.black, "", inline = "SD", group = g_SET)
track = input.bool(true, "Track Start Price", tooltip = "Track the price that indicates the beginning of a gap (previous session close)", group = g_SET)
ext = input.bool(false, "Extend Boxes", tooltip = "Extend gaps the right of the chart", group = g_SET)
keep_last = input.int(10, "Keep Last", 1, tooltip = "Delete drawings beyond this number of sessions ago", group = g_SET)
tf_limit = input.timeframe("30", "Timeframe Limit", tooltip = "Drawings will not show on timeframes greater than this", group = g_SET)

var box[] eth = array.new_box()

var line[] start = array.new_line()

var line[] q1 = array.new_line()
var line[] q2 = array.new_line()
var line[] q3 = array.new_line()

var line[] DL = array.new_line()

t = not na(time("", session, "America/New_York"))

if timeframe.in_seconds() <= timeframe.in_seconds(tf_limit)
    if t and not t[1]
        if eth.size() > 0
            eth.get(0).set_right(time)

            q1.get(0).set_x2(time)
            q2.get(0).set_x2(time)
            q3.get(0).set_x2(time)

        eth.unshift(box.new(time, close[1], time, close[1], xloc = xloc.bar_time, bgcolor = na, border_color = na, extend = ext ? extend.right : extend.none))

        start.unshift(line.new(time, close[1], time, close[1], xloc = xloc.bar_time, color = na, style = line.style_dotted, extend = ext ? extend.right : extend.none))

        q1.unshift(line.new(time, close[1], time, close[1], xloc = xloc.bar_time, color = na, style = line.style_dashed, extend = ext ? extend.right : extend.none))
        q2.unshift(line.new(time, close[1], time, close[1], xloc = xloc.bar_time, color = na, style = line.style_solid,  extend = ext ? extend.right : extend.none))
        q3.unshift(line.new(time, close[1], time, close[1], xloc = xloc.bar_time, color = na, style = line.style_dashed, extend = ext ? extend.right : extend.none))

        if delineations
            DL.unshift(line.new(time, high, time, low, xloc = xloc.bar_time, extend = extend.both, color = del_color, style = line.style_dotted))
    else if not t and t[1]
        eth.get(0).set_left(time)

        if track
            start.get(0).set_x2(time)
            start.get(0).set_color(del_color)

        q1.get(0).set_x1(time)
        q2.get(0).set_x1(time)
        q3.get(0).set_x1(time)

        eth.get(0).set_top(open > eth.get(0).get_top() ? open : eth.get(0).get_top())
        eth.get(0).set_bottom(open < eth.get(0).get_top() ? open : eth.get(0).get_bottom())

        top = eth.get(0).get_top()
        bottom = eth.get(0).get_bottom()
        h = (top - bottom)
        qr = h / 4

        q1.get(0).set_y1(top - qr * 1)
        q2.get(0).set_y1(top - qr * 2)
        q3.get(0).set_y1(top - qr * 3)
        
        q1.get(0).set_y2(top - qr * 1)
        q2.get(0).set_y2(top - qr * 2)
        q3.get(0).set_y2(top - qr * 3)

        if delineations
            DL.unshift(line.new(time, high, time, low, xloc = xloc.bar_time, extend = extend.both, color = del_color, style = line.style_dotted))

        box_color = top > start.get(0).get_y1() ? gap_up_color : gap_dn_color
        line_color = top > start.get(0).get_y1() ? color.new(gap_up_color, 0) : color.new(gap_dn_color, 0)

        eth.get(0).set_bgcolor(box_color)
        eth.get(0).set_border_color(box_color)
        
        q1.get(0).set_color(line_color)
        q2.get(0).set_color(line_color)
        q3.get(0).set_color(line_color)

        if eth.size() > keep_last
            box.delete(eth.pop())
            
            if track
                line.delete(start.pop())

            line.delete(q1.pop())
            line.delete(q2.pop())
            line.delete(q3.pop())

            if delineations
                line.delete(DL.pop())
                line.delete(DL.pop())

    if not t
        if eth.size() > 0
            eth.get(0).set_right(time)

            q1.get(0).set_x2(time)
            q2.get(0).set_x2(time)
            q3.get(0).set_x2(time)

    if t
        if eth.size() > 0 and track
            start.get(0).set_x2(time)