Multi timeframes RSI Screener & indicator by noop42
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © noop42

//@version=4
study("MTF RSI Screener & indicator by noop42", overlay=false)

// Input parameters
src = input(close, title="Source")
repainting = input(title="Allow repaint ? (enabled = live values)", type=input.bool, defval=true, group="Options")
show_screener = input(title="Show Screener", type=input.bool, defval=true, group="Options")
show_lines = input(title="Show RSI lines ?", type=input.bool, defval=true, group="Options")

tf1 = input(title="Timeframe 1", type=input.resolution, defval="5", group="Options")
tf2 = input(title="Timeframe 2", type=input.resolution, defval="15", group="Options")
tf3 = input(title="Timeframe 3", type=input.resolution, defval="60", group="Options")
tf4 = input(title="Timeframe 4", type=input.resolution, defval="240", group="Options")

tf1_cvg_opt = input(true, "Include Timeframe #1 in convergence signals", group="Options")
tf2_cvg_opt = input(true, "Include Timeframe #2 in convergence signals", group="Options")
tf3_cvg_opt = input(true, "Include Timeframe #3 in convergence signals", group="Options")
tf4_cvg_opt = input(false, "Include Timeframe #4 in convergence signals", group="Options")

lengthRSI = input(14, "RSI Length", minval=1, group="RSI")
rsi_low = input(30, title="RSI Oversold Level", group="RSI")
rsi_high = input(70, title="RSI Overbought Level", group="RSI")

// Custom functions
rp_security(_symbol, _res, _src) => security(_symbol, _res, _src[barstate.isrealtime ? (repainting ? 0 : 1) : 0], gaps=false)
get_movement(rsi) => rsi > rsi[1] ? "Bull" : "Bear"
show_drawings(data) => show_lines ? data : na

// MTF RSI
rsi_tf1 = rp_security(syminfo.tickerid, tf1, rsi(src,lengthRSI))
rsi_tf2 = rp_security(syminfo.tickerid, tf2, rsi(src,lengthRSI))
rsi_tf3 = rp_security(syminfo.tickerid, tf3, rsi(src,lengthRSI))
rsi_tf4 = rp_security(syminfo.tickerid, tf4, rsi(src,lengthRSI))

rsi1ob = rsi_tf1 > rsi_high
rsi1os = rsi_tf1 < rsi_low
rsi2ob = rsi_tf2 > rsi_high
rsi2os = rsi_tf2 < rsi_low
rsi3ob = rsi_tf3 > rsi_high
rsi3os = rsi_tf3 < rsi_low
rsi4ob = rsi_tf4 > rsi_high
rsi4os = rsi_tf4 < rsi_low

tf1mov = get_movement(rsi_tf1)
tf2mov = get_movement(rsi_tf2)
tf3mov = get_movement(rsi_tf3)
tf4mov = get_movement(rsi_tf4)

// Colors
obColor = color.blue
osColor = #d43128
bullColor = #20b8e6
bearColor = color.red

tf1movColor = tf1mov == "Bull" ? bullColor : bearColor
tf2movColor = tf2mov == "Bull" ? bullColor : bearColor
tf3movColor = tf3mov == "Bull" ? bullColor : bearColor
tf4movColor = tf4mov == "Bull" ? bullColor : bearColor

tf1RSIColor = rsi1ob ? obColor : rsi1os ? osColor : tf1movColor
tf2RSIColor = rsi2ob ? obColor : rsi2os ? osColor : tf2movColor
tf3RSIColor = rsi3ob ? obColor : rsi3os ? osColor : tf3movColor
tf4RSIColor = rsi4ob ? obColor : rsi4os ? osColor : tf4movColor

tf1status = rsi1ob ? "Overbought" : rsi1os ? "Oversold" : "OK"
tf2status = rsi2ob ? "Overbought" : rsi2os ? "Oversold" : "OK"
tf3status = rsi3ob ? "Overbought" : rsi3os ? "Oversold" : "OK"
tf4status = rsi4ob ? "Overbought" : rsi4os ? "Oversold" : "OK"

// Convergences
rsi_ob_convergence = (tf1_cvg_opt ? rsi1ob : true) and (tf2_cvg_opt ? rsi2ob : true) and (tf3_cvg_opt ? rsi3ob : true) and (tf4_cvg_opt ? rsi4ob : true)
rsi_os_convergence = (tf1_cvg_opt ? rsi1os : true) and (tf2_cvg_opt ? rsi2os : true) and (tf3_cvg_opt ? rsi3os : true) and (tf4_cvg_opt ? rsi4os : true)

// Screener
default_bg = #cccccc
var tbl = table.new(position.top_right, 4, 6)
if (show_screener)
    if (barstate.islast)
        table.cell(tbl, 0, 0, "TimeFrame",  bgcolor = default_bg)
        table.cell(tbl, 1, 0, "RSI", bgcolor = default_bg)
        table.cell(tbl, 2, 0, "Movement", bgcolor = default_bg)
        table.cell(tbl, 3, 0, "RSI Status", bgcolor = default_bg)

        table.cell(tbl, 0, 1, tf1+(tf1_cvg_opt ? "*" : ""),  bgcolor = default_bg)
        table.cell(tbl, 1, 1, tostring(rsi_tf1, '#.##'), bgcolor = tf1RSIColor)
        table.cell(tbl, 2, 1, tf1mov, bgcolor = tf1RSIColor)
        table.cell(tbl, 3, 1, tf1status, bgcolor = tf1RSIColor)

        table.cell(tbl, 0, 2, tf2+(tf2_cvg_opt ? "*" : ""),  bgcolor = default_bg)
        table.cell(tbl, 1, 2, tostring(rsi_tf2, '#.##'), bgcolor = tf2RSIColor)
        table.cell(tbl, 2, 2, tf2mov, bgcolor = tf2RSIColor)
        table.cell(tbl, 3, 2, tf2status, bgcolor = tf2RSIColor)

        table.cell(tbl, 0, 3, tf3+(tf3_cvg_opt ? "*" : ""),  bgcolor = default_bg)
        table.cell(tbl, 1, 3, tostring(rsi_tf3, '#.##'), bgcolor = tf3RSIColor)
        table.cell(tbl, 2, 3, tf3mov, bgcolor = tf3RSIColor)
        table.cell(tbl, 3, 3, tf3status, bgcolor = tf3RSIColor)

        table.cell(tbl, 0, 4, tf4+(tf4_cvg_opt ? "*" : ""),  bgcolor = default_bg)
        table.cell(tbl, 1, 4, tostring(rsi_tf4, '#.##'), bgcolor = tf4RSIColor)
        table.cell(tbl, 2, 4, tf4mov, bgcolor = tf4RSIColor)
        table.cell(tbl, 3, 4, tf4status, bgcolor = tf4RSIColor)
        
        // Warning convergence alerts
        rsi_warning_message = (rsi_os_convergence ? "RSI OS convergence" : rsi_ob_convergence ? "RSI OB convergence" : "No RSI warning")
        rsi_warning_color = rsi_os_convergence ? osColor : rsi_ob_convergence ? obColor : default_bg

        table.cell(tbl, 0, 5, "Warnings",  bgcolor = color.orange)
        table.cell(tbl, 1, 5, rsi_warning_message, bgcolor = rsi_warning_color)        

// Oscillators
// Zones & lines
ob_zone_color = obColor
os_zone_color = osColor
invisible = #00000000

h0 = hline(show_drawings(rsi_high), "Upper Band", color=ob_zone_color)
hmid = hline(show_drawings(50), "Middle Band", color=#ffffff45)
h1 = hline(show_drawings(rsi_low), "Lower Band", color=os_zone_color)
obZone = hline(show_drawings(rsi_high), color=invisible)
osZone = hline(show_drawings(rsi_low), color=invisible)

plot(show_drawings(rsi_tf1), "RSI #1", color=tf1RSIColor, linewidth=1, transp=20)
plot(show_drawings(rsi_tf2), "RSI #2", color=tf2RSIColor, linewidth=2, transp=40)
plot(show_drawings(rsi_tf3), "RSI #3", color=tf3RSIColor, linewidth=3, transp=60)
plot(show_drawings(rsi_tf4), "RSI #4", color=tf4RSIColor, linewidth=4, transp=80)

// Shapes
plotshape(show_drawings(rsi_os_convergence) ? 1 : 0, color=bullColor, location=location.bottom, size=size.tiny, style=shape.triangleup, title="Bullish movement")
plotshape(show_drawings(rsi_ob_convergence) ? 1 : 0, color=bearColor, location=location.top, size=size.tiny, style=shape.triangledown, title="Bearish movement")
