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

//@version=5
indicator("VWAP Gaps", overlay = true, max_lines_count = 50)

// ---------- Functions ---------- //

// TradingView vwap function. Taken out stdev calcs to put in seperate function. 
computeVWAP(src, isNewPeriod) =>
	var float sumSrcVol = na
	var float sumVol = na
    var float sumSrcSrcVol = na

	sumSrcVol := isNewPeriod ? src * volume : src * volume + sumSrcVol[1]
	sumVol := isNewPeriod ? volume : volume + sumVol[1]
	// sumSrcSrcVol calculates the dividend of the equation that is later used to calculate the standard deviation
	sumSrcSrcVol := isNewPeriod ? volume * math.pow(src, 2) : volume * math.pow(src, 2) + sumSrcSrcVol[1]

	_vwap = sumSrcVol / sumVol


previouslevels(period, VWAP) =>
    var float pL = na
    pL := period ? VWAP[1] : pL


// Function adapted from script "Naked - Daily Weekly Monthly" by Frien_dd
untappedVWAP(p_vwap, isNewPeriod) =>
    var line[]  vwapLinesUp = array.new_line()
    var float[] p_vwapUp  = array.new_float()
    var line[]  vwapLinesDown = array.new_line()
    var float[] p_vwapDown  = array.new_float()

    if isNewPeriod
        array.push(vwapLinesUp, line.new(time, p_vwap, time+1, p_vwap, xloc=xloc.bar_time, style=line.style_solid, color=color.orange, extend=extend.right))
        array.push(vwapLinesDown, line.new(time, p_vwap, time+1, p_vwap, xloc=xloc.bar_time, style=line.style_solid, color=color.orange, extend=extend.right))
        array.push(p_vwapUp, p_vwap)
        array.push(p_vwapDown, p_vwap)
    
    if array.size(p_vwapUp) > 0
        for i = 0 to array.size(p_vwapUp)-1
            vwapUp = array.get(p_vwapUp,i)
            if vwapUp < high
                line.delete(array.get(vwapLinesUp,i))

        for i = 0 to array.size(p_vwapDown)-1
            vwapDown = array.get(p_vwapDown,i)
            if vwapDown > low 
                line.delete(array.get(vwapLinesDown,i))



// ---------- VWAP selection ---------- //

src = input(hlc3, "VWAP Source")
vwap_selection = input.string(title = "VWAP Options", defval="Day", options = ["Day", "Week", "Month", "Quarter", "Year"])
plot_vwap = input(true, "Plot vwap")
vwapGap = input(true, 'Plot VWAP Gap levels')
plot_pL = input(true, 'Plot pVWAP levels')

// ---------- VWAP Calculations ---------- //

timeChange(period) =>
	ta.change(time(period))

newSession = vwap_selection == "Day" ? timeChange("D") : 
         vwap_selection == "Week" ? timeChange("W") : 
         vwap_selection == "Month" ? timeChange("M") : 
         vwap_selection == "Quarter" ? timeChange("3M") : 
         vwap_selection == "Year" ? timeChange("12M") : na

// ---------- VWAP Function Calls ---------- //

_vwap = vwap_selection == "Day" ? computeVWAP(src, newSession) : 
         vwap_selection == "Week" ? computeVWAP(src, newSession) : 
         vwap_selection == "Month" ? computeVWAP(src, newSession) : 
         vwap_selection == "Quarter" ? computeVWAP(src, newSession) : 
         vwap_selection == "Year" ? computeVWAP(src, newSession) : na

p_vwap = previouslevels(newSession, _vwap)


// ---------- Plots ---------- //

v_plot = plot(plot_vwap ? _vwap : na, title = "VWAP", color = color.new(color.white, 25), style = plot.style_stepline, linewidth = 1)

if vwapGap
    untappedVWAP(p_vwap, newSession)

pV = previouslevels(newSession, _vwap)
pVplot = plot(plot_pL ? pV : na, title = "Previous VWAP", color = color.orange, style = plot.style_linebr, transp = 60, linewidth = 1)


//-------------------- Sweeps --------------------//

// Only calculates sweeps from the previous period. 

vwap_sweep = input(true, 'Plot pVWAP sweep')

// Filters
bull = close > open
bear = close < open
sweep_up = open < pV and high > pV and close < pV 
sweep_down = open > pV and low < pV and close > pV 
v_under = _vwap < pV
v_over = _vwap > pV


barcolor(sweep_up and v_under ? color.red : sweep_down and v_over ? color.green : na)

plotshape(vwap_sweep ? sweep_up and bear and v_under : na, style=shape.triangledown,
                 location=location.abovebar, color=color.red, size = size.tiny)
plotshape(vwap_sweep ? sweep_down and bull and v_over : na, style=shape.triangleup,
                 location=location.belowbar, color=color.white, size = size.tiny)
