True Range/Expected Move
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © robertsullivan1956
//@version=5
name="True Range/Expected Move"
indicator(name, overlay=false)

volSymbol = input.string("VOLI", "VOL Symbol", ["VIX", "VIX1D", "VIX9D", "VIXMO", "VXW3", "VXW4", "VXW5", "VXW6", "VINXE", "UVXY", "VOLI"])
tradingDaysInYear = input.int(365, "Trading days in year", minval=200, maxval=365, step=1, tooltip="Use 256 for Rule Of 16")
colorShift = input.float(1, "Color shift value", minval=0, maxval=2.00, step=0.01, tooltip="Ratio value for the bar color changes.")
shortTradingDay = input.bool(false, "Short trading session?")
displayShading = input.bool(true, "Display color between 1 STD and 1/2 STD?")
volValue = request.security(volSymbol, "1", open)

// ApplyRange() applies the given minimum and maximum
// to the range of the specified value. Returns value
// unchanged when it's inside the minimum-maximum range.
// This will limit the upper and lower boundaries of the study.
ApplyRange(value, minimum, maximum) =>
    math.min(math.max(value, minimum), maximum)

// Calculate a 1 standard deviation move on SPX using the chosen volatility.
// first calculate the fraction of the trading day remaining.
minsInTradingDay = shortTradingDay ? 3.5 * 60 : 6.5 * 60 // 3.5 hour session or 6.5 hour session
lastSessionMinute = shortTradingDay ? 13 * 60 : 16 * 60 // Session ends at 1 pm or 4 pm
frac = (lastSessionMinute - (hour * 60 + minute)) / minsInTradingDay
timeRemaining = math.sqrt(frac) / math.sqrt(tradingDaysInYear)
sd = close * (volValue/100) * timeRemaining

// True Range vs Expected Move
var maxExpectedMove = 10e-10
var hi = 10e-10
var lo = 10e10
taHigh = ta.highest(1)
taLow = ta.lowest(1)

if dayofmonth(time) != dayofmonth(time[1])
    hi := 10e-10
    lo := 10e10
    maxExpectedMove := 10e-10

maxExpectedMove := math.max(maxExpectedMove, sd)
hi := math.max(taHigh, hi)
lo := math.min(taLow, lo)
tr = hi - lo
trueRangeAbove = close + tr
trueRangeBelow = close - tr

trueRangeRelativeToExpectedMove = ApplyRange(tr/maxExpectedMove, 0, 4)   

trVsEmColor = trueRangeRelativeToExpectedMove > colorShift ? color.green : color.red
plot(trueRangeRelativeToExpectedMove, "True Range vs Expected Move", style = plot.style_columns, color = trVsEmColor)