Measure Volume, Momentum, Trend, Volatility
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © kfatkin

//@version=5
indicator(title="Measure Volume, Momentum, Trend, Volatility", shorttitle="Measure Volume/Momentum/Trend/Volatility", format=format.price, precision=2, timeframe="", timeframe_gaps=true, overlay=false)

// Parameters Input Section

// RSI Inputs
showRsi = input(true, "Show RSI (Momentum)", inline="Dispay RSI", group="RSI")
lengthRsi = input.int(14, "Length", inline="Configure RSI", minval=1, maxval=200, group="RSI")
sourceRsi = input(close, "Source", inline="Configure RSI", group="RSI")
rsiHighLevelPlot = input.int(70, "Overbought Level", inline="RSI Levels", group="RSI")
rsiLowLevelPlot = input.int(30, "Oversold Level", inline="RSI Levels", group="RSI")
colorRsiBull = input(color.white, "Bull Color", inline="RSI Line Colors", group="RSI")
colorRsiBear = input(color.white, "Bear Color", inline="RSI Line Colors", group="RSI")
rsiBackgroundFillColor = input(color.purple, "Background Color", inline="RSI Background Colors", group="RSI")
rsiBackgroundTransparency = input.int(90, "Background Transparency", inline="RSI Background Colors", group="RSI")

rsiMiddleLevelPlot = input.int(50, "Middle RSI/MFI Level", inline="RSI/MFI Settings", group="RSI/MFI")
rsiSeperatorColor = input(color.white, "RSI/MFI Seperator Color", inline="RSI/MFI Settings", group="RSI/MFI")

// MFI Inputs
showMfi = input(true, "Show MFI (Volume)", inline="Display MFI", group="MFI")
lengthMfi = input.int(14, "Length", minval=1, maxval=200, inline="Configure MFI", group="MFI")
sourceMfi = input(hlc3, "Source", inline="Configure MFI", group="MFI")
mfiHighLevelPlot = input.int(80, "Overbought MFI Level", inline="MFI Levels", group="MFI")
mfiLowLevelPlot = input.int(20, "Oversold MFI Level", inline="MFI Levels", group="MFI")
colorMfiBull = input(color.fuchsia, "Bull Color", inline="MFI Line Colors", group="MFI")
colorMfiBear = input(color.fuchsia, "Bear Color", inline="MFI Line Colors", group="MFI")
mfiHighLevelColor = input(color.green, "MFI High Background Color", inline="MFI Background Colors", group="MFI")
mfiLowLevelColor = input(color.red, "MFI Low Background Color", inline="MFI Background Colors", group="MFI")
mfiBackgroundTransparency =  input.int(90, "MFI Background Transparency", inline="MFI Background Colors", group="MFI")

// DMI Inputs
showDmi = input(true, "Show DMI (Volatility)", inline="DMI", group="DMI")
lengthDmi = input.int(14, "Length", inline="Configure MI", minval=1, maxval=200, group="DMI")
lengthSigDmi = input.int(14, "Signal Length", inline="Configure DMI", minval=1, maxval=50, group="DMI")
strongAdxSignal = input.int(20, "Strong ADX Level", minval=1, inline="DMI Levels", group="DMI" )
colorDmiAdx = input(color.yellow, "ADX Color", inline="DMI Colors", group="DMI")
colorDmiWeakAdx = input(color.gray, "Weak ADX Color", inline="DMI Colors", group="DMI")
dmiTrans =  input.int(65, "DMI Transparency", inline="DMI Colors", group="DMI")
colorDmiDiPlus = input(color.lime, "DI +", inline="DI Colors", group="DMI")
colorDmiDiMinus = input(color.red, "DI -", inline="DI Colors", group="DMI")


// Parabolic SAR Inputs
showPsar = input(true, "Show Parabolic SAR (Trend)", inline="Show SAR", group="SAR")
psarStart = input(0.02, "Start", inline="SAR Start", group="SAR")
psarIncrement = input(0.02, "Increment", inline="SAR Inc", group="SAR")
psarMax = input(0.2, "Max Value", inline="SAR Max", group="SAR")
pricePeriod = input(ohlc4, "Source", inline="SAR Period", group="SAR")
psarBullColor = input(color.green, "Bull Color", inline="SAR Color", group="SAR")
psarBearColor = input(color.red, "Bear Color", inline="SAR Color", group="SAR")
psarTrans =  input.int(55, "Transparency", inline="SAR Color", group="SAR")

// Indicators Section 

// RSI
rsi = ta.rsi(sourceRsi, lengthRsi) 

// MFI
mf = ta.mfi(sourceMfi, lengthMfi)

// DMI
up = ta.change(high)
down = -ta.change(low)
plusDM = na(up) ? na : (up > down and up > 0 ? up : 0)
minusDM = na(down) ? na : (down > up and down > 0 ? down : 0)
trur = ta.rma(ta.tr, lengthDmi)
plus = fixnan(100 * ta.rma(plusDM, lengthDmi) / trur)
minus = fixnan(100 * ta.rma(minusDM, lengthDmi) / trur)
sum = plus + minus
adx = (100 * ta.rma(math.abs(plus - minus) / (sum == 0 ? 1 : sum), lengthSigDmi))
goodVolatility = adx >= strongAdxSignal
adxColor = goodVolatility ? colorDmiAdx : colorDmiWeakAdx
determineDiWinner = plus > minus
diWinner = determineDiWinner ? plus : minus

// Parabolic SAR
psarOut = ta.sar(psarStart, psarIncrement, psarMax)
price = request.security(syminfo.tickerid, timeframe.period, pricePeriod)
psarAbovePrice = psarOut >= price

// Drawing Section

// Plot ADX symbols
diColor = determineDiWinner ? colorDmiDiPlus : colorDmiDiMinus
plotchar(showDmi ? adx : na, "Show ADX", color = showDmi ? color.new(adxColor, dmiTrans) : na, char = '•', location = location.top, size = size.small) 
plotchar(showDmi ? diWinner : na, "Show DI", color = showDmi ? color.new(diColor, dmiTrans) : na, char = '•', location = location.top, size = size.tiny) 

// Plot RSI and MFI Lines
rsiBullColor = color.from_gradient(rsi, rsiMiddleLevelPlot, rsiHighLevelPlot, color.new(colorRsiBull, 10), color.new(colorRsiBull, 0))
rsiBearColor = color.from_gradient(rsi, rsiLowLevelPlot, rsiMiddleLevelPlot, color.new(colorRsiBear,   0), color.new(colorRsiBear, 10))
rsiColor = rsi > rsiMiddleLevelPlot ? rsiBullColor : rsiBearColor
plot(showRsi ? rsi : na, color = showRsi ? rsiColor : na, style = plot.style_line)

mfiBullColor = color.from_gradient(mf, rsiMiddleLevelPlot, mfiHighLevelPlot, color.new(colorMfiBull, 10), color.new(colorMfiBull, 0))
mfiBearColor = color.from_gradient(mf, mfiLowLevelPlot, rsiMiddleLevelPlot, color.new(colorMfiBear,   0), color.new(colorMfiBear, 10))
mfiColor = mf > rsiMiddleLevelPlot ? colorMfiBull : colorMfiBear
plot(showMfi ? mf : na, "MFI", color= showMfi ? mfiColor : na, style = plot.style_line)

hline(rsiMiddleLevelPlot, title="Middle Line", linestyle=hline.style_dotted)
rsiHighLevel = hline(rsiHighLevelPlot, title="RSI Overbought", linestyle=hline.style_dotted, color=rsiSeperatorColor)
rsiLowLevel = hline(rsiLowLevelPlot, title="RSI Oversold", linestyle=hline.style_dotted, color=rsiSeperatorColor)
fill(rsiHighLevel, rsiLowLevel, title="RSI/MFI Background", color=color.new(rsiBackgroundFillColor, rsiBackgroundTransparency))
mfiHighLevel = hline(mfiHighLevelPlot, title="MFI Overbought", linestyle=hline.style_dotted, color=rsiSeperatorColor)
mfiLowLevel = hline(mfiLowLevelPlot, title="MFI Oversold", linestyle=hline.style_dotted, color=rsiSeperatorColor)
oscMaxLevel = hline(100, title="Oscillator Max", linestyle=hline.style_solid, color=color.new(rsiSeperatorColor, 100))
oscMinLevel = hline(0, title="Oscillator Min", linestyle=hline.style_solid, color=color.new(rsiSeperatorColor, 100))
fill(rsiHighLevel, mfiHighLevel, title="MFI Overbought Background", color=color.new(mfiHighLevelColor, mfiBackgroundTransparency))
fill(mfiLowLevel, rsiLowLevel, title="MFI Oversold Background", color=color.new(mfiLowLevelColor, mfiBackgroundTransparency))

// Plot Parabolic SAR Symbols
signalColor = psarAbovePrice ? psarBearColor : psarBullColor
plotchar(showPsar ? psarOut : na, "ParabolicSAR", color= showPsar ? color.new(signalColor, psarTrans) : na , char= showPsar ? '◆' : na, location = showPsar ? location.bottom : na, size = size.tiny)