Volume Spike Backfills
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Vostok369

//@version=5
indicator("Volume Spike Backfills", shorttitle='VS Fills', overlay=true)


///// VOLUME SPIKES

volumePercent = input.int(150, title = "Volume Spike Candles (%)", tooltip="Marks candles with volume greater than a percentage of the previous candle average volume", minval = 100, maxval = 1000, step = 10)
avLookback = input.int(10, title = "Candle Average Lookback", tooltip="Can deviate from the standard 10 candle average")
timeframe = input.string(title = "Timeframe", defval = "Auto", options=["Auto", "5", "15", "30", "60" ])
GreenLB = input.int(4, title = "Green Volume Spike Look Back", tooltip="Alter to see more or less green bands on the chart", minval = 1, maxval = 10, step = 1)
RedLB = input.int(4, title = "Red Volume Spike Look Back", tooltip="Alter to see more or less red bands on the chart", minval = 1, maxval = 10, step = 1)
MaxLB = input.bool(false, title = "Max Look Back", tooltip="See a larger number of bands on the chart for an at a glance view of historical volume spikes")
EQbreak = input.int(50, title = "Median Break of Candle (%)", tooltip="Alter to view approximately how much of the candle body has been backfilled", minval = 20, maxval = 80, step = 10)
Complete = input.int(0, title = "Backfill completed within ($)", tooltip="Alter to remove bands that are almost completely backfilled or too small to be significant")
showVS = input.bool(true, title = "Show VS Labels")


ColorRed = input.color(color.new(color.red, 100) , title="Red Levels")
RedFill = input.color(color.new(color.red, 80), title="Red Fill First Level")
RedEQFill = input.color(color.new(color.red, 90), title="Red Fill SecondLevel")
ColorGreen = input.color(color.new(color.green, 100) , title="Green Levels")
GreenFill = input.color(color.new(color.green, 80), title="Green Fill First Level")
GreenEQFill = input.color(color.new(color.green, 90), title="Green Fill Second Level")


if timeframe == 'Auto'
    timeframe := timeframe.period


[tflow, tfhigh, tftime, tfvol, tfopen, tfclose] = request.security(syminfo.tickerid, timeframe, [low, high, time, volume, open, close], lookahead=barmerge.lookahead_on)

candle = 'Green'
if tfclose < tfopen
    candle := 'Red'

if MaxLB
    GreenLB := 20
    RedLB := 20

var volStore = array.new_float()
var volLabels = array.new_label()

total = 0.0

if array.size(volStore) >= avLookback
    for i = 0 to array.size(volStore) - 1
        total += array.get(volStore, i)

average = total/10


/// add volume store
if array.size(volStore) >= avLookback
    array.shift(volStore)

array.push(volStore, tfvol)


var oLineRed = array.new_line()
var oLineGreen = array.new_line()
var cLineRed = array.new_line()
var cLineGreen = array.new_line()
var mLineRed = array.new_line()
var mLineGreen = array.new_line()



for x = 0 to 4
    if array.size(oLineGreen) > 0
        for i = 0 to array.size(oLineGreen) - 1
            if array.size(oLineGreen) >= i+1
                checkLineClose = array.get(cLineGreen, i)
                checkLineOpen = array.get(oLineGreen, i)
                checkLineEQ = array.get(mLineGreen, i)
                checkOpen = line.get_y2(checkLineOpen)
                checkClose = line.get_y2(checkLineClose)
                checkEQ = line.get_y2(checkLineEQ)
                
                if tflow < checkOpen + Complete
                    line.delete(array.remove(cLineGreen, i))
                    line.delete(array.remove(oLineGreen, i))                 
                    line.delete(array.remove(mLineGreen, i))  
                else if tflow < checkEQ
                    line.set_y1(checkLineClose, tflow)
                    line.set_y2(checkLineClose, tflow)
                    line.set_y1(checkLineEQ, tflow)
                    line.set_y2(checkLineEQ, tflow)
                else if tflow < checkClose
                    line.set_y1(checkLineClose, tflow)
                    line.set_y2(checkLineClose, tflow)


for x = 0 to 4
    if array.size(oLineRed) > 0
        for i = 0 to array.size(oLineRed) - 1
            if array.size(oLineRed) >= i+1
                checkLineClose = array.get(cLineRed, i)
                checkLineOpen = array.get(oLineRed, i)
                checkLineEQ = array.get(mLineRed, i)
                checkOpen = line.get_y2(checkLineOpen)
                checkClose = line.get_y2(checkLineClose)
                checkEQ = line.get_y2(checkLineEQ)


                if tfhigh > checkOpen - Complete
                    line.delete(array.remove(cLineRed, i))
                    line.delete(array.remove(oLineRed, i))                 
                    line.delete(array.remove(mLineRed, i)) 
                  
                else if tfhigh > checkEQ
                    line.set_y1(checkLineClose, tfhigh)
                    line.set_y2(checkLineClose, tfhigh)
                    line.set_y1(checkLineEQ, tfhigh)
                    line.set_y2(checkLineEQ, tfhigh)
                else if tfhigh > checkClose
                    line.set_y1(checkLineClose, tfhigh)
                    line.set_y2(checkLineClose, tfhigh)
                
     
pAverage = math.round((tfvol/average)*100)  
vString = str.tostring(pAverage) + ' %'

alertVScandle = false

if tfvol > average * (volumePercent/100)
    alertVScandle := true
    if candle == 'Red'
        oLine = line.new(x1=tftime, x2=tftime + 1, y1=tfopen, y2=tfopen, color=ColorRed, xloc=xloc.bar_time, extend=extend.right)
        cLine = line.new(x1=tftime, x2=tftime + 1, y1=tfclose, y2=tfclose, color=ColorRed, xloc=xloc.bar_time, extend=extend.right)
        
        eq = tfclose + math.abs(tfopen-tfclose)*(EQbreak/100)

        mLine = line.new(x1=tftime, x2=tftime + 1, y1=eq, y2=eq, color=ColorRed, xloc=xloc.bar_time, extend=extend.right)

        array.push(oLineRed, oLine)
        array.push(cLineRed, cLine)    
        array.push(mLineRed, mLine) 

        if showVS
            vLabel = label.new(x=tftime, y=tflow, text=vString, xloc=xloc.bar_time, color=color.rgb(165, 0, 0), textcolor= color.white, style=label.style_label_up , size=size.small)
          
       

    if candle == 'Green'
        oLine = line.new(x1=tftime, x2=tftime + 1, y1=tfopen, y2=tfopen, color=ColorGreen, xloc=xloc.bar_time, extend=extend.right)
        cLine = line.new(x1=tftime, x2=tftime + 1, y1=tfclose, y2=tfclose, color=ColorGreen, xloc=xloc.bar_time, extend=extend.right)

        eq = tfclose - math.abs(tfopen-tfclose)*(EQbreak/100)

        mLine = line.new(x1=tftime, x2=tftime + 1, y1=eq, y2=eq, color=ColorGreen, xloc=xloc.bar_time, extend=extend.right)
       
        array.push(oLineGreen, oLine)
        array.push(cLineGreen, cLine)    
        array.push(mLineGreen, mLine)   

        if showVS
            vLabel = label.new(x=tftime, y=tfhigh, text=vString, xloc=xloc.bar_time, color=color.rgb(25, 92, 19), textcolor= color.white, style=label.style_label_down , size=size.small) 


if array.size(oLineRed) > RedLB
    line.delete(array.shift(oLineRed))
    line.delete(array.shift(cLineRed))
    line.delete(array.shift(mLineRed))

if array.size(oLineGreen) > GreenLB
    line.delete(array.shift(oLineGreen))
    line.delete(array.shift(cLineGreen))
    line.delete(array.shift(mLineGreen))




if barstate.islast
    if array.size(oLineRed) > 0
        for i = 0 to array.size(oLineRed) - 1
            checkLineClose = array.get(cLineRed, i)
            checkLineOpen = array.get(oLineRed, i)
            checkLineEQ = array.get(mLineRed, i)
            checkEQ = line.get_y2(checkLineOpen)
            checkClose = line.get_y2(checkLineClose)
            
            linefill.new(checkLineOpen, checkLineEQ, RedEQFill)
            if checkEQ != checkClose
                linefill.new(checkLineEQ, checkLineClose, RedFill)

           

    if array.size(oLineGreen) > 0
        for i = 0 to array.size(oLineGreen) - 1
            checkLineClose = array.get(cLineGreen, i)
            checkLineOpen = array.get(oLineGreen, i)
            checkLineEQ = array.get(mLineGreen, i)
            checkEQ = line.get_y2(checkLineOpen)
            checkClose = line.get_y2(checkLineClose)
            
            linefill.new(checkLineOpen, checkLineEQ, GreenEQFill)
            if checkEQ != checkClose
                linefill.new(checkLineEQ, checkLineClose, GreenFill)


/// alerts

alertcondition(alertVScandle, 'Volume Spike', 'Volume spike occured on timeframe' )






