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

//VWAP is the abbreviation for volume-weighted average price, which is a technical analysis tool that shows the ratio of an asset's price to its total trade volume. It provides traders 
//and investors with a measure of the average price at which a stock is traded over a given period of time. This indicator shows both the Rolling VWAP and Standard Deviations as set by the user. 
//The Rolling VWAP calculation is similar to the stardard VWAP although it caclulates the volume weighted average price over the specified period of time (lookback) resetting for each subsequent bar. 

//The unique aspect of this indicator is that instead of calculating the RVWAP over the current timeframes lookback period the option is available to select a High-Time-Frame setting instead. 
//This has two different methods of calculation
//1 - Based on HTF security requests (both repainting and non-repainting)
//2 - Automatic calculation of number of current timeframe bars that make up the HTF lookback period (smoother and non-repainting plot)

//Addionally a smooth function is included for the HTF input setting. 

//@version=5
indicator('Koalafied RVWAP', overlay=true)

// ---------- FUNCTIONS ---------- //

computeVWAP(src, vol, len, stDevMultiplier1, stDevMultiplier2, stDevMultiplier3) =>
    sumSrcVol = 0.0
    sumVol = 0.0
    sumSrcSrcVol = 0.0
    for i = 1 to len - 1 by 1
        sumSrcVol := vol[i] + sumSrcVol
        sumVol := vol[i] * src[i] + sumVol
        sumSrcSrcVol := vol[i] * math.pow(src[i], 2) + sumSrcSrcVol
        sumSrcSrcVol

    _vwap = sumVol / sumSrcVol
    variance = sumSrcSrcVol / sumSrcVol - math.pow(_vwap, 2)
    variance := variance < 0 ? 0 : variance
    stDev = math.sqrt(variance)

    upperBand3 = _vwap + stDev * stDevMultiplier3
    upperBand2 = _vwap + stDev * stDevMultiplier2
    upperBand1 = _vwap + stDev * stDevMultiplier1
    lowerBand1 = _vwap - stDev * stDevMultiplier1
    lowerBand2 = _vwap - stDev * stDevMultiplier2
    lowerBand3 = _vwap - stDev * stDevMultiplier3

    [_vwap, upperBand3, upperBand2, upperBand1, lowerBand1, lowerBand2, lowerBand3 ]

// ————— Converts current "timeframe.multiplier" plus the TF into minutes of type float.
f_resInMinutes() => 
    _resInMinutes = timeframe.multiplier * (
      timeframe.isseconds ? 1. / 60. :
      timeframe.isminutes ? 1.       :
      timeframe.isdaily   ? 1440.    :
      timeframe.isweekly  ? 10080.   :
      timeframe.ismonthly ? 43800.   : na)

// ————— Returns resolution of _resolution period in minutes.
f_tfResInMinutes(_res) =>
    // _res: resolution of any TF (in "timeframe.period" string format).
    request.security(syminfo.tickerid, _res, f_resInMinutes())

// Returns the theoretical numbers of current chart bars in the given target HTF resolution (note that this number maybe very different from actual number on certain symbols).
f_theoreticalDilationOf(_res) =>
    // _res: resolution of any TF (in "timeframe.period" string format).
    f_tfResInMinutes(_res) / f_resInMinutes()
    
// ---------- INPUTS ---------- //

var GRP1 = "INPUTS"
_len = input(30, 'rVWAP Length', group = GRP1) 
HTF = input.timeframe("D", "Resolution", group = GRP1)
showStd = input(false, 'Show Deviations', group = GRP1)
fill_bands = input(true, 'Fill Std Dev bands')
stDevMultiplier_1 = input(1.0, "StDev mult 1", group = GRP1)
stDevMultiplier_2 = input(2.0, "StDev mult 2", group = GRP1)
stDevMultiplier_3 = input(3.0, "StDev mult 2", group = GRP1)

var GRP2 = "HTF PARAMETERS"
HTF_switch = input(false, "Use HTF input", group = GRP2)
HTFRepaints = input(false, "Allow HTF Repainting", group = GRP2)
HTF_Smooth = input(false,  "Smooth Higher Timeframes", group = GRP2)
HTF_Smooth_len = input.int(1, "Smoothing Factor", minval = 1, group = GRP2)

src = hlc3
vol = volume
_mult = f_theoreticalDilationOf(HTF)

// ---------- RVWAP ---------- //

[rVWAP, stup3, stup2, stup1, stdn1, stdn2, stdn3] = computeVWAP(src, vol, HTF_switch ? _len : _len * _mult, stDevMultiplier_1, stDevMultiplier_2, stDevMultiplier_3)

vHtfSmoothLen = math.max(2, _len / HTF_Smooth_len)

rVWAP_out = not HTF_switch ? rVWAP : HTFRepaints ? request.security(syminfo.tickerid, HTF, rVWAP) : request.security(syminfo.tickerid, HTF, rVWAP[1], lookahead = barmerge.lookahead_on)
rVWAP_out := HTF_switch and HTF_Smooth ? ta.ema(ta.ema(ta.ema(rVWAP_out, vHtfSmoothLen), vHtfSmoothLen), vHtfSmoothLen) : rVWAP_out

stup3_out = not HTF_switch ? stup3 : HTFRepaints ? request.security(syminfo.tickerid, HTF, stup3) : request.security(syminfo.tickerid, HTF, stup3[1], lookahead = barmerge.lookahead_on)
stup3_out := HTF_switch and HTF_Smooth ? ta.ema(ta.ema(ta.ema(stup3_out, vHtfSmoothLen), vHtfSmoothLen), vHtfSmoothLen) : stup3_out

stup2_out = not HTF_switch ? stup2 : HTFRepaints ? request.security(syminfo.tickerid, HTF, stup2) : request.security(syminfo.tickerid, HTF, stup2[1], lookahead = barmerge.lookahead_on)
stup2_out := HTF_switch and HTF_Smooth ? ta.ema(ta.ema(ta.ema(stup2_out, vHtfSmoothLen), vHtfSmoothLen), vHtfSmoothLen) : stup2_out

stup1_out = not HTF_switch ? stup1 : HTFRepaints ? request.security(syminfo.tickerid, HTF, stup1) : request.security(syminfo.tickerid, HTF, stup1[1], lookahead = barmerge.lookahead_on)
stup1_out := HTF_switch and HTF_Smooth ? ta.ema(ta.ema(ta.ema(stup1_out, vHtfSmoothLen), vHtfSmoothLen), vHtfSmoothLen) : stup1_out

stdn1_out = not HTF_switch ? stdn1 : HTFRepaints ? request.security(syminfo.tickerid, HTF, stdn1) : request.security(syminfo.tickerid, HTF, stdn1[1], lookahead = barmerge.lookahead_on)
stdn1_out := HTF_switch and HTF_Smooth ? ta.ema(ta.ema(ta.ema(stdn1_out, vHtfSmoothLen), vHtfSmoothLen), vHtfSmoothLen) : stdn1_out

stdn2_out = not HTF_switch ? stdn2 : HTFRepaints ? request.security(syminfo.tickerid, HTF, stdn2) : request.security(syminfo.tickerid, HTF, stdn2[1], lookahead = barmerge.lookahead_on)
stdn2_out := HTF_switch and HTF_Smooth ? ta.ema(ta.ema(ta.ema(stdn2_out, vHtfSmoothLen), vHtfSmoothLen), vHtfSmoothLen) : stdn2_out

stdn3_out = not HTF_switch ? stdn3 : HTFRepaints ? request.security(syminfo.tickerid, HTF, stdn3) : request.security(syminfo.tickerid, HTF, stdn3[1], lookahead = barmerge.lookahead_on)
stdn3_out := HTF_switch and HTF_Smooth ? ta.ema(ta.ema(ta.ema(stdn3_out, vHtfSmoothLen), vHtfSmoothLen), vHtfSmoothLen) : stdn3_out


// ---------- Plots ---------- //
fill_colup = color.new(color.red, 95)
fill_colmid = color.new(color.gray, 95)
fill_coldown = color.new(color.blue, 95)

rVWAP_col = not HTF_switch ? close > rVWAP ? color.blue : color.red : close > rVWAP_out ? color.blue : color.red

Mid = plot(rVWAP_out, color = rVWAP_col, style=plot.style_stepline, linewidth=1)
s3up_A = plot(showStd ? stup3_out : na, title='VWAP - STDEV 3U', color=color.new(color.red, 90), style=plot.style_stepline, linewidth=2)
s2up_A = plot(showStd ? stup2_out : na, title='VWAP - STDEV 2U', color=color.new(color.red, 80), style=plot.style_stepline, linewidth=2)
s1up_A = plot(showStd ? stup1_out : na, title='VWAP - STDEV 1U', color=color.new(color.gray, 70), style=plot.style_stepline, linewidth=2)
s1dn_A = plot(showStd ? stdn1_out : na, title='VWAP - STDEV 1D', color=color.new(color.gray, 70), style=plot.style_stepline, linewidth=2)
s2dn_A = plot(showStd ? stdn2_out : na, title='VWAP - STDEV 2D', color=color.new(color.blue, 80), style=plot.style_stepline, linewidth=2)
s3dn_A = plot(showStd ? stdn3_out : na, title='VWAP - STDEV 3D', color=color.new(color.blue, 90), style=plot.style_stepline, linewidth=2)

fill(s3up_A, s1up_A, color = fill_bands ? fill_colup : na)
fill(s2up_A, s1up_A, color = fill_bands ? fill_colup : na)
fill(s1up_A, Mid, color = fill_bands ? fill_colmid : na)
fill(s1dn_A, Mid, color = fill_bands ? fill_colmid : na)
fill(s2dn_A, s1dn_A, color = fill_bands ? fill_coldown : na)
fill(s3dn_A, s1dn_A, color = fill_bands ? fill_coldown : na)

