True Range Moving Average Deviation
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © gabasco

//@version=5
indicator(title="True Range Moving Average Deviation", shorttitle="TRMAD", precision=2, timeframe="", overlay=false)

// 1. Input
themeInput     = input.string("Standard",                  title="Theme      ", options=["Standard", "Light"], inline = 'theme', group="General Settings", display=display.none)
colorLineInput = input.color(color.new(color.black, 10), title= "",                                          inline = 'theme', group="General Settings", display=display.none)
obValueInput   = input.float(3,                            title="Overbought",                                 inline = 'ob',    group="General Settings", display=display.none)
obColorInput   = input(#089981,                          title="",                                           inline = 'ob',    group="General Settings", display=display.none)
osValueInput   = input.float(-3,                           title="Oversold    ",                               inline = 'os',    group="General Settings", display=display.none)
osColorInput   = input(#f23645,                          title="",                                           inline = 'os',    group="General Settings", display=display.none)

trTypeInput    = input.string("SMA", title="TR Type", options=["SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA"],                       group="TR Settings", display=display.none)
trLengthInput  = input.int(14, "TR Length", minval=2,                                                                            group="TR Settings", display=display.none)

maTypeInput    = input.string("SMA", title="MA Type", options=["SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA"],                       group="MA Settings", display=display.none)
maLengthInput  = input.int(20, "MA Length", minval=2,                                                                            group="MA Settings", display=display.none)


// 2. Formula
ma(source, length, type) =>
    switch type
        "SMA" => ta.sma(source, length)
        "EMA" => ta.ema(source, length)
        "SMMA (RMA)" => ta.rma(source, length)
        "WMA" => ta.wma(source, length)
        "VWMA" => ta.vwma(source, length)

// 3. Calculation
atr      = ma(ta.tr(true), trLengthInput, trTypeInput)
distance = close - ma(close, maLengthInput, maTypeInput)
trmad    = nz(distance/atr)

// 4. Drawings
// a. TRMAD
trmadPlot = plot(trmad, "TRMAD", themeInput == "Standard" ? trmad > obValueInput ? obColorInput : trmad < osValueInput ? osColorInput : colorLineInput : colorLineInput, editable = false)

// b. Zero line
zeroPlot = plot(0,                                 editable=false, display=display.none)
obPlot   = plot(trmad > obValueInput ? trmad : na, editable=false, display=display.none)
osPlot   = plot(trmad < osValueInput ? trmad : na, editable=false, display=display.none)

// c. Fills
// - Above/below zero line
fill(zeroPlot, trmadPlot, themeInput == "Standard" ? trmad < 0 ? color.new(osColorInput,90) : color.new(obColorInput, 90) : chart.bg_color, title = "Area Fill") 

// - Overbought / oversold zone
fill(zeroPlot, obPlot, obValueInput * 1.5, obValueInput,        top_color = themeInput == "Standard" ? color.new(obColorInput, 50)  : na, bottom_color = themeInput == "Standard" ? color.new(obColorInput, 100) : na, title = "Overbought Gradient Fill")
fill(zeroPlot, osPlot, osValueInput,       osValueInput * 1.5,  top_color = themeInput == "Standard" ? color.new(osColorInput, 100) : na, bottom_color = themeInput == "Standard" ? color.new(osColorInput, 0)   : na, title = "Oversold Gradient Fill")

// d. Levels
// - Hidden
obLevel  = plot(obValueInput, color = na, editable = false, display=display.none)
midLevel = plot(0,            color = na, editable = false, display=display.none)
osLevel  = plot(osValueInput, color = na, editable = false, display=display.none)

// - Displayed
hline(obValueInput, 'Overbought')
hline(0,            'Midline')
hline(osValueInput, 'Oversold')