Candle Gaps
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ivanroyloewen

//@version=5
indicator("Candle Gaps", overlay = true, max_boxes_count = 50)
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Input
// the colour that the gaps will be
colour_Of_Gaps = input(title = "Gap Colour", defval = color.black)
// start drawing the left of the gaps box at the previous candles wick or from the current candle
draw_Gap_From_Wick = input(title = "Start Gaps From Wicks", defval = false)
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Handle Down Gaps
// create an array for all the down gaps
var down_Gaps = array.new<box>(0)
// draw the down gaps
Draw_Down_Gaps() =>
    // check if there is an down gap on the present candle...
    if close < low[1]
        // there is... draw an down box
        box down_box = box.new(bar_index[draw_Gap_From_Wick ? 1 : 0], low[1], bar_index, close, border_color = na, bgcolor = colour_Of_Gaps, extend = extend.right)
        // add it to the down_Gaps array
        array.push(down_Gaps, down_box)

// fill in down gaps as price crosses over them
Fill_In_Down_Gaps() =>
    // loop through all the down gaps
    for [index, value] in down_Gaps
        // check if the loop gap ( value ) is the present candle, if it is keep looping ( prevents the present candle gap from being filled always)...
        if value.get_left() != bar_index[draw_Gap_From_Wick ? 1 : 0]
            // it is not... check if the high of the current candle is higher than the bottom of the loop gap ( value )...
            if high > value.get_bottom()
                // it is... check if the present candle high is above the loop gap ( value ) top...
                if high < value.get_top()
                    // it is... set the bottom of the loop gap ( value ) to the high of the present candle, partially filling in the gap
                    value.set_bottom(high)
                else
                    // it is not... the current candle high is higher than the loop gap ( value ) top, the gap is entirely filled, delete it
                    value.delete()

//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Handle Up Gaps
// create an array for all the up gaps
var up_Gaps = array.new<box>(0)
// draw the up gaps
Draw_Up_Gaps() =>
    // check if there is an up gap on the present candle...
    if close > high[1]
        // there is... draw an up box
        box up_Gap = box.new(bar_index[draw_Gap_From_Wick ? 1 : 0], close, bar_index, high[1], border_color = na, bgcolor = colour_Of_Gaps, extend = extend.right)
        // add it to the up_Gaps array
        array.push(up_Gaps, up_Gap)
// fill in up gaps as price crosses over them
Fill_In_Up_Gaps() =>
    // loop through all the up gaps
    for [index, value] in up_Gaps
        // check if the loop gap ( value ) is the present candle, if it is keep looping ( prevents the present candle gap from being filled always)...
        if value.get_left() != bar_index[draw_Gap_From_Wick ? 1 : 0]
            // it is not... check if the low of the current candle is lower than the top of the loop gap ( value )...
            if low < value.get_top()
                // it is... check if the present candle low is above the loop gap ( value ) bottom...
                if low > value.get_bottom()
                    // it is... set the top of the loop gap ( value ) to the low of the present candle, partially filling in the gap
                    value.set_top(low)
                else
                    // it is not... the current candle low is lower than the loop gap ( value ) bottom, the gap is entirely filled, delete it
                    value.delete()
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Execution
// execute all gap drawing functions
Draw_Down_Gaps()
Draw_Up_Gaps()
// execute all gap filling functions
Fill_In_Down_Gaps()
Fill_In_Up_Gaps()
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------