Daily Opening GAP
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//@version=5

indicator("Daily GAP", shorttitle="Gaps", overlay=true,max_boxes_count=150,max_lines_count = 200)

session = input.session("0930-1600","Session Period",options=["0930-1600"])
line_width = input.int(1,"Box Line Width",1,4)
plot_boxes = input.bool(true,"Plot Boxes")
plot_lines = input.bool(false,"Plot Lines")
plot_mid_line = input.bool(true,"Plot Middle Line")
plot_qtr_line = input.bool(false,"Plot Quarter Line")
border_color = input.color(color.yellow,"Border Color")
fill_color = input.color(color.new(color.yellow,90),"Border Color")
mid_color = input.color(color.yellow,"Mid Color")
qtr_color = input.color(color.yellow,"Qtr Color")


t = time("D", session, "America/New_York")
bool is_new_day = na(t[1]) and not na(t) or t[1] < t
bool in_session = not na(time(timeframe.period, session, "America/New_York"))
bool is_close = not na(t[1]) and na(t) or t[1] < t

float prior_close = na

var line[] gap_levels = array.new_line()
var box[] gap_boxes = array.new_box()

prior_close := prior_close[1]

if is_close
    prior_close := close[1]

if is_new_day
    
    top = open > prior_close ? open : prior_close
    bottom = open < prior_close ? open : prior_close
    mid = (top+bottom)/2
  
    if plot_lines
        array.push(gap_levels,line.new(bar_index-1,top,bar_index,top,xloc.bar_index,extend = extend.right,color =border_color,style = line.style_solid,width=line_width))
        array.push(gap_levels,line.new(bar_index-1,bottom,bar_index,bottom,xloc.bar_index,extend = extend.right,color =border_color,style = line.style_solid,width=line_width))
    if plot_mid_line
        array.push(gap_levels,line.new(bar_index-1,mid,bar_index,mid,xloc.bar_index,extend = extend.right,color =border_color,style = line.style_dashed,width=math.max(1,line_width/2)))
    
    if plot_qtr_line
        top_qtr = (top+mid)/2
        bottom_qtr = (bottom+mid)/2
        array.push(gap_levels,line.new(bar_index-1,top_qtr,bar_index,top_qtr,xloc.bar_index,extend = extend.right,color =border_color,style = line.style_dashed,width=math.max(1,line_width/2)))
        array.push(gap_levels,line.new(bar_index-1,bottom_qtr,bar_index,bottom_qtr,xloc.bar_index,extend = extend.right,color =border_color,style = line.style_dashed,width=math.max(1,line_width/2)))
    
    if plot_boxes
        array.push(gap_boxes,box.new(bar_index-1,top,bar_index+10,bottom,border_color,line_width,line.style_solid,extend.right,xloc.bar_index,fill_color))


if in_session
    removals = array.new_int()
    for [lineNo,this_line] in gap_levels
        y = line.get_y1(this_line)
        if (low <= y and high >= y)
            line.set_x2(this_line,bar_index)
            line.set_extend(this_line,extend.none)
            removals.push(lineNo)
    
    while removals.size() > 0
        removal = removals.pop()
        array.remove(gap_levels,removal)


    for [boxNo,gap_box] in gap_boxes
        h = box.get_top(gap_box)
        l = box.get_bottom(gap_box)
        if (low < h and high[1] >= h)
            removals.push(boxNo)
            
            box.set_right(gap_box,bar_index)
            box.set_extend(gap_box,extend.none)

            if low > l
                array.push(gap_boxes,box.new(bar_index,low,bar_index+1,l,border_color,line_width,line.style_solid,extend.right,xloc.bar_index,fill_color))
            

        else if ( high > l and low[1] <= l)
            removals.push(boxNo)

            box.set_right(gap_box,bar_index)
            box.set_extend(gap_box,extend.none)
            
            if high < h
                array.push(gap_boxes,box.new(bar_index,h,bar_index+1,high,border_color,line_width,line.style_solid,extend.right,xloc.bar_index,fill_color))
        
        while removals.size() > 0
            removal = removals.pop()
            array.remove(gap_boxes,removal)
            
