High Low Bars in Color
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © MrJulius

// @version=5

// Color is determined by change in midpoints between high and low (hl2). Traditional direction is indicated by "frosting" markers
// for open ("+") and close("x").

// Best used in combination with High Low Color Volume.

indicator("High Low Bars in Color", overlay=true)

// constants
string  COLOR_METHOD_TOOLTIP = "Standard deviation threshold refers to vector change in hl2 from one bar to the next. The SMA delta absolute values method uses a percentage threshold. Percent change threshold is useful for an overview of volatility. Tritone is up/down/flat hl2 without any in-between shading."

// inputs
color   upcolorInput             = input.color(color.rgb(0, 137, 123, 0), "Up", group = "Color Palette")
color   downcolorInput           = input.color(color.rgb(255, 82, 82, 0), "Down", group = "Color Palette")
color   flatcolorInput           = input.color(color.rgb(97, 55, 145, 0), "Flat", group = "Color Palette")
color   bordertoneInput          = input.color(color.rgb(160, 160, 160, 0), "Border", group="Frosting")
bool    drawborderInput          = input.bool(true, "Border frosting", group = "Frosting")
bool    showopencloseInput       = input.bool(false, "Open and close frosting", group = "Frosting")
string  colormethodInput         = input.string("StDev", "Color method", ["StDev", "SMA D Abs",  "Percent", "Tritone"],
                                                  COLOR_METHOD_TOOLTIP, group = "Color Method")
float   stdevInput               = input.float(1.2, "Standard deviation threshold", group = "Color Method")
int     percentileInput          = input.int(150, "Percentage of SMA for hl2 delta absolute values", group = "Color Method")
int     deltasmalengthInput      = input.int(30, "Length for St Dev or SMA", group = "Color Method")
float   percentchangeInput       = input.float(0.05, "Percent change threshold", group = "Color Method")

// traditional doji
traddoji = close == open

// set color
difference = hl2 - hl2[1]
deltapercent = 100*difference / hl2[1]
deltastdev = ta.stdev(difference, deltasmalengthInput)
deltaabs = math.abs(difference)
deltaabssma = ta.sma(deltaabs, deltasmalengthInput)

color candlecolor = switch colormethodInput
    "StDev"     => difference > deltastdev * stdevInput ? upcolorInput :
                   difference > 0 ?
                      color.from_gradient(difference * 100 / (deltastdev * stdevInput), 0, 100, flatcolorInput, upcolorInput) :
                   difference == 0 ? flatcolorInput :
                   difference > -1 * deltastdev * stdevInput ? 
                      color.from_gradient(difference * 100 / (deltastdev * stdevInput), -100, 0, downcolorInput, flatcolorInput) :
                   downcolorInput
    "SMA D Abs" => difference > deltaabssma * percentileInput / 100 ? upcolorInput :
                   difference > 0 ? 
                      color.from_gradient(difference * 10000 / (deltaabssma * percentileInput), 0, 100, flatcolorInput, upcolorInput) :
                   difference == 0 ? flatcolorInput :
                   difference > -1 * deltaabssma * percentileInput / 100 ? 
                      color.from_gradient(difference * 10000 / (deltaabssma * percentileInput), -100, 0, downcolorInput, flatcolorInput) :
                   downcolorInput
    "Percent"   => deltapercent > percentchangeInput ? upcolorInput :
                   deltapercent > 0 ? 
                      color.from_gradient(deltapercent * 100 / percentchangeInput, 0, 100, flatcolorInput, upcolorInput) :
                   deltapercent == 0 ? flatcolorInput :
                   deltapercent > -1 * percentchangeInput ? 
                      color.from_gradient(deltapercent * 100 / percentchangeInput, -100, 0, downcolorInput, flatcolorInput) :
                   downcolorInput
    "Tritone"   => hl2 > hl2[1] ? upcolorInput : hl2 < hl2[1] ? downcolorInput : flatcolorInput

// plot candle body
plotcandle(high, high, low, low, color=candlecolor, bordercolor = drawborderInput ? bordertoneInput : candlecolor, wickcolor=na, title="High Low Color")

// plot open and close frosting
plotshape(showopencloseInput and not traddoji ? open : na, "open", shape.cross, location.absolute, color.white, size=size.tiny)
plotshape(showopencloseInput and not traddoji ? close : na, "close", shape.xcross, location.absolute, color.white, size=size.tiny)
plotshape(showopencloseInput and traddoji ? open : na, "open = close", shape.diamond, location.absolute, color.white, size=size.tiny)