Average Daily Range Lines + VWAP by Tenozen
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Tenozen

//@version=5
indicator("Average Daily Range Lines + VWAP by Tenozen", shorttitle="ADRL + VWAP", overlay=true)

lengthInput = input.int(19, title="ADR Length")
smaHigh = ta.sma(high, lengthInput)
smaLow = ta.sma(low, lengthInput)
adr_per = input.int(100, title="ADR percent value target?")
adr = smaHigh - smaLow
sum = ta.cum(adr)


is_new_day = ta.change(time("D"))


var float adr_target = 0

if (is_new_day)
    adr_target := is_new_day? adr*adr_per : na

var float adr_total = 0

if (is_new_day)
    adr_total := sum

adr_total_fix = sum - adr_total



cross = ta.crossover(adr_total_fix, adr_target) //the key point

cm = ta.valuewhen(cross, (high+low)/2, 0)
ch = ta.valuewhen(cross, high, 0)
cl = ta.valuewhen(cross, low, 0)

plot(cm, title="Mid line", style = plot.style_stepline, color= #311adf)
h_line = plot(ch, title="High line", style = plot.style_stepline, color= #311adf)
l_line = plot(cl, title="Low line", style = plot.style_stepline, color= #311adf)

bgcolor(is_new_day ? color.new(color.blue, 85) : na)
plot(adr_total_fix)
plot(adr_target, color=color.yellow)
fill(h_line, l_line, color=color.new(color.white, 95), title= "Box Fill Color")
///////////////////////////////VWAP///////////////////////////////////////////////
var cumVol = 0.
cumVol += nz(volume)
if barstate.islast and cumVol == 0
    runtime.error("No volume is provided by the data vendor.")

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
	variance = sumSrcSrcVol / sumVol - math.pow(_vwap, 2)
	variance := variance < 0 ? 0 : variance
	stDev = math.sqrt(variance)

	[_vwap, stDev]

computeStdevBands(value, stdev, bandMult) =>
    float upperBand = value + stdev * bandMult
    float lowerBand = value - stdev * bandMult
    [upperBand, lowerBand]

hideonDWM = input(false, title="Hide VWAP on 1D or Above", group="VWAP Settings")
var anchor = input.string(defval = "ADR", title="Anchor Period",
 options=["ADR","Session", "Week", "Month", "Quarter", "Year", "Decade", "Century", "Earnings", "Dividends", "Splits"], group="VWAP Settings")
src = input(title = "Source", defval = hlc3, group="VWAP Settings")
offset = input(0, title="Offset", group="VWAP Settings")

showBand_1 = input(false, title="", group="Standard Deviation Bands Settings", inline="band_1")
stdevMult_1 = input(1.0, title="Bands Multiplier #1", group="Standard Deviation Bands Settings", inline="band_1")
showBand_2 = input(false, title="", group="Standard Deviation Bands Settings", inline="band_2")
stdevMult_2 = input(2.0, title="Bands Multiplier #2", group="Standard Deviation Bands Settings", inline="band_2")
showBand_3 = input(false, title="", group="Standard Deviation Bands Settings", inline="band_3")
stdevMult_3 = input(3.0, title="Bands Multiplier #3", group="Standard Deviation Bands Settings", inline="band_3")

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

new_earnings = request.earnings(syminfo.tickerid, earnings.actual, barmerge.gaps_on, barmerge.lookahead_on, ignore_invalid_symbol=true)
new_dividends = request.dividends(syminfo.tickerid, dividends.gross, barmerge.gaps_on, barmerge.lookahead_on, ignore_invalid_symbol=true)
new_split = request.splits(syminfo.tickerid, splits.denominator, barmerge.gaps_on, barmerge.lookahead_on, ignore_invalid_symbol=true)

isNewPeriod = switch anchor
	"Earnings" => not na(new_earnings)
	"Dividends" => not na(new_dividends)
	"Splits" => not na(new_split)
	"Session" => timeChange("D")
	"Week" => timeChange("W")
	"Month" => timeChange("M")
	"Quarter" => timeChange("3M")
	"Year" => timeChange("12M")
	"Decade" => timeChange("12M") and year % 10 == 0
	"Century" => timeChange("12M") and year % 100 == 0
	"ADR" =>  ta.crossover(adr_total_fix, adr_target)
	=> false

isEsdAnchor = anchor == "Earnings" or anchor == "Dividends" or anchor == "Splits"
if na(src[1]) and not isEsdAnchor
	isNewPeriod := true

float vwapValue = na
float stdev = na
float upperBandValue1 = na
float lowerBandValue1 = na
float upperBandValue2 = na
float lowerBandValue2 = na
float upperBandValue3 = na
float lowerBandValue3 = na

if not (hideonDWM and timeframe.isdwm)
    [_vwap, _stdev] = computeVWAP(src, isNewPeriod)
    vwapValue := _vwap
    stdev := _stdev
	[upBV1, loBV1] = computeStdevBands(vwapValue, stdev, stdevMult_1)
	upperBandValue1 := showBand_1 ? upBV1 : na
	lowerBandValue1 := showBand_1 ? loBV1 : na
	[upBV2, loBV2] = computeStdevBands(vwapValue, stdev, stdevMult_2)
	upperBandValue2 := showBand_2 ? upBV2 : na
	lowerBandValue2 := showBand_2 ? loBV2 : na
	[upBV3, loBV3] = computeStdevBands(vwapValue, stdev, stdevMult_3)
	upperBandValue3 := showBand_3 ? upBV3 : na
	lowerBandValue3 := showBand_3 ? loBV3 : na

plot(vwapValue, title="VWAP", color=color.white, offset=offset)

upperBand_1 = plot(upperBandValue1, title="Upper Band #1", color=color.green, offset=offset)
lowerBand_1 = plot(lowerBandValue1, title="Lower Band #1", color=color.green, offset=offset)
fill(upperBand_1, lowerBand_1, title="Bands Fill #1", color= color.new(color.green, 95))

upperBand_2 = plot(upperBandValue2, title="Upper Band #2", color=color.olive, offset=offset)
lowerBand_2 = plot(lowerBandValue2, title="Lower Band #2", color=color.olive, offset=offset)
fill(upperBand_2, lowerBand_2, title="Bands Fill #2", color= color.new(color.olive, 95))

upperBand_3 = plot(upperBandValue3, title="Upper Band #3", color=color.teal, offset=offset)
lowerBand_3 = plot(lowerBandValue3, title="Lower Band #3", color=color.teal, offset=offset)
fill(upperBand_3, lowerBand_3, title="Bands Fill #3", color= color.new(color.teal, 95))
