RSI Radar Multi Time Frame
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © LonesomeTheBlue
 
get_rsi(rsiarr, rsih)=>
    float rsix = na
    if not na(rsiarr)
        if array.size(rsiarr) > 0 
            rsix := array.get(rsiarr, array.size(rsiarr) - 1)
    rsix := not na(rsix) ? rsix : rsih

get_time_string(T)=>
    ret = T == "" ? timeframe.period : T

//@version=5
indicator("RSI Radar Multi Time Frame", overlay=true)
T1 = input.timeframe(defval = "")
T2 = input.timeframe(defval = "1")
T3 = input.timeframe(defval = "15")
T4 = input.timeframe(defval = "60")
T5 = input.timeframe(defval = "240")
T6 = input.timeframe(defval = "1D")
Rsicolor = input.color(defval = color.blue, title = "RSI line", inline = "rsi")
Rsiwidth = input.int(defval = 3, title = "", minval = 1, maxval = 10, inline = "rsi")
curved = input.bool(true, title = "Curved", inline = "rsi")
obcolor = input.color(defval = color.rgb(255, 0, 0, 65), title = "OB/OS Colors", inline = "colors")
oscolor = input.color(defval = color.rgb(0, 255, 0, 65), title = "", inline = "colors")
rsilabels = input.bool(true, title = "Labels")
circle = input.bool(true, title = "Circles")

var times = array.new_int(0)
if barstate.isnew or barstate.islastconfirmedhistory
    array.push(times, time)

// we need to use bar index because for non 7/24 markets polyline shape may be corrupted
leftbarindex = array.indexof(times, chart.left_visible_bar_time)
rightbarindex = array.indexof(times, chart.right_visible_bar_time)
if rightbarindex == -1 
    rightbarindex := array.size(times) - 1

visibletime = rightbarindex - leftbarindex
timestep = math.round(visibletime / 100)
mid = (ta.highest(300) + ta.lowest(300)) / 2
diff = ta.highest(300) - ta.lowest(300)
len = diff / 3
mult = 1.1

xpoints = array.new_int(14)
ypoints = array.new_float(14)
array.set(xpoints, 0, leftbarindex + timestep * 46)
array.set(ypoints, 0, mid + len * mult)
array.set(xpoints, 1, leftbarindex + timestep * 54)
array.set(ypoints, 1, mid)
array.set(xpoints, 2, leftbarindex + timestep * 46)
array.set(ypoints, 2, mid - len * mult)
array.set(xpoints, 3, leftbarindex + timestep * 30)
array.set(ypoints, 3, mid - len * mult)
array.set(xpoints, 4, leftbarindex + timestep * 22)
array.set(ypoints, 4, mid)
array.set(xpoints, 5, leftbarindex + timestep * 30)
array.set(ypoints, 5, mid + len * mult)

midpx = leftbarindex + timestep * 38
midpy = mid

pointx = array.new_int(0)
pointy = array.new_float(0)
RsiArray = array.new_float(0)
osx = array.new_int(0)
osy = array.new_float(0)

min1arr = request.security_lower_tf(syminfo.tickerid, T1, ta.rsi(close, 14), ignore_invalid_timeframe = true)
min1rsi_2 = request.security(syminfo.tickerid, T1, ta.rsi(close, 14))
min1rsi = get_rsi(min1arr, min1rsi_2)
array.push(pointx, midpx + math.round(min1rsi * (array.get(xpoints, 1) - midpx) / 200))
array.push(pointy, midpy + min1rsi * (array.get(ypoints, 0) - midpy) / 100)
array.push(osx, midpx + math.round(30 * (array.get(xpoints, 1) - midpx) / 200))
array.push(osy, midpy + 30 * (array.get(ypoints, 0) - midpy) / 100)
array.push(RsiArray, min1rsi)
array.set(xpoints, 11, midpx + math.round(70 * (array.get(xpoints, 1) - midpx) / 200))
array.set(ypoints, 11, midpy + 70 * (array.get(ypoints, 0) - midpy) / 100)

min1arr := request.security_lower_tf(syminfo.tickerid, T2, ta.rsi(close, 14), ignore_invalid_timeframe = true)
min1rsi_2 := request.security(syminfo.tickerid, T2, ta.rsi(close, 14))
min1rsi := get_rsi(min1arr, min1rsi_2)
array.push(pointx, midpx + math.round(min1rsi * (array.get(xpoints, 1) - midpx) / 100))
array.push(pointy, midpy)
array.push(osx, midpx + math.round(30 * (array.get(xpoints, 1) - midpx) / 100))
array.push(osy, midpy)
array.push(RsiArray, min1rsi)
array.set(xpoints, 10, midpx + math.round(70 * (array.get(xpoints, 1) - midpx) / 100))
array.set(ypoints, 10, midpy)

min1arr := request.security_lower_tf(syminfo.tickerid, T3, ta.rsi(close, 14), ignore_invalid_timeframe = true)
min1rsi_2 := request.security(syminfo.tickerid, T3, ta.rsi(close, 14))
min1rsi := get_rsi(min1arr, min1rsi_2)
array.push(pointx, midpx + math.round(min1rsi * (array.get(xpoints, 2) - midpx) / 100))
array.push(pointy, midpy - min1rsi * (midpy - array.get(ypoints, 2)) / 100)
array.push(osx, midpx + math.round(30 * (array.get(xpoints, 2) - midpx) / 100))
array.push(osy, midpy - 30 * (midpy - array.get(ypoints, 2)) / 100)
array.push(RsiArray, min1rsi)
array.set(xpoints, 9, midpx + math.round(70 * (array.get(xpoints, 2) - midpx) / 100))
array.set(ypoints, 9, midpy - 70 * (midpy - array.get(ypoints, 2)) / 100)

min1arr := request.security_lower_tf(syminfo.tickerid, T4, ta.rsi(close, 14), ignore_invalid_timeframe = true)
min1rsi_2 := request.security(syminfo.tickerid, T4, ta.rsi(close, 14))
min1rsi := get_rsi(min1arr, min1rsi_2)
array.push(pointx, midpx - math.round(min1rsi * (midpx - array.get(xpoints, 3)) / 100))
array.push(pointy, midpy - min1rsi * (midpy - array.get(ypoints, 3)) / 100)
array.push(osx, midpx - math.round(30 * (midpx - array.get(xpoints, 3)) / 100))
array.push(osy, midpy - 30 * (midpy - array.get(ypoints, 3)) / 100)
array.push(RsiArray, min1rsi)
array.set(xpoints, 8, midpx - math.round(70 * (midpx - array.get(xpoints, 3)) / 100))
array.set(ypoints, 8, midpy - 70 * (midpy - array.get(ypoints, 3)) / 100)

min1arr := request.security_lower_tf(syminfo.tickerid, T5, ta.rsi(close, 14), ignore_invalid_timeframe = true)
min1rsi_2 := request.security(syminfo.tickerid, T5, ta.rsi(close, 14))
min1rsi := get_rsi(min1arr, min1rsi_2)
array.push(pointx, midpx - math.round(min1rsi * (midpx - array.get(xpoints, 4)) / 100))
array.push(pointy, midpy)
array.push(osx, midpx - math.round(30 * (midpx - array.get(xpoints, 4)) / 100))
array.push(osy, midpy)
array.push(RsiArray, min1rsi)
array.set(xpoints, 7, midpx - math.round(70 * (midpx - array.get(xpoints, 4)) / 100))
array.set(ypoints, 7, midpy)

min1arr := request.security_lower_tf(syminfo.tickerid, T6, ta.rsi(close, 14), ignore_invalid_timeframe = true)
min1rsi_2 := request.security(syminfo.tickerid, T6, ta.rsi(close, 14))
min1rsi := get_rsi(min1arr, min1rsi_2)
array.push(pointx, midpx - math.round(min1rsi * (midpx - array.get(xpoints, 5)) / 100))
array.push(pointy, midpy + min1rsi * (array.get(ypoints, 5) - midpy) / 100)
array.push(osx, midpx - math.round(30 * (midpx - array.get(xpoints, 5)) / 100))
array.push(osy, midpy + 30 * (array.get(ypoints, 5) - midpy) / 100)
array.push(RsiArray, min1rsi)
array.set(xpoints, 6, midpx - math.round(70 * (midpx - array.get(xpoints, 5)) / 100))
array.set(ypoints, 6, midpy + 70 * (array.get(ypoints, 5) - midpy) / 100)
array.set(xpoints, 12, array.get(xpoints, 6))
array.set(ypoints, 12, array.get(ypoints, 6))
array.set(xpoints, 13, array.get(xpoints, 5))
array.set(ypoints, 13, array.get(ypoints, 5))

get_text(T, rsival)=>
    ret = "Res: " + get_time_string(T) + '\nRSI: ' + str.tostring(rsival, '#.##')

get_color(rsival)=>
    backgr = rsival < 30 ? color.green : rsival > 70 ? color.red : color.black
    txt = rsival < 30 ? color.black : rsival > 70 ? color.white : color.white
    array.from(backgr, txt)

get_all_colors(rsiarray)=>
    colors = matrix.new<color>()
    for x = 0 to 5
        matrix.add_row(colors, x, get_color(array.get(rsiarray, x)))
    colors

if barstate.islast    
    mainpoints = array.new<chart.point>()
    for x = 0 to 13
        mainpoints.push(chart.point.from_index(array.get(xpoints, x), array.get(ypoints, x)))

    points30 = array.new<chart.point>()
    for x = 0 to 5
        points30.push(chart.point.from_index(array.get(osx, x), array.get(osy, x)))   

    var polyline plnos = na
    polyline.delete(plnos)
    plnos := polyline.new(points30, curved = false, closed = true, fill_color = oscolor, line_style = line.style_dotted)

    var polyline plnm = na
    polyline.delete(plnm)
    plnm := polyline.new(mainpoints, curved = false, closed = true, fill_color = obcolor)

    colors = get_all_colors(RsiArray)
    if rsilabels
        labels = array.new_label(0)
        for x = 1 to (array.size(labels) > 0 ? array.size(labels) : na)
            label.delete(array.pop(labels))
        
        var styles = array.from(label.style_label_lower_left, label.style_label_left, label.style_label_upper_left, label.style_label_upper_right, label.style_label_right, label.style_label_lower_right)
        var TFs = array.from(T1, T2, T3, T4, T5, T6)
        for x = 0 to 5
            array.push(labels, label.new(array.get(xpoints, x), array.get(ypoints, x), text = get_text(array.get(TFs, x), array.get(RsiArray, x)), color = matrix.get(colors, x, 0) , textcolor = matrix.get(colors, x, 1), style = array.get(styles, x)))

    var centerlines = array.new_line(0)
    for x = 1 to (array.size(centerlines) > 0 ? array.size(centerlines) : na)
        line.delete(array.pop(centerlines))
    array.push(centerlines, line.new(x1 = array.get(xpoints, 0), y1 = array.get(ypoints, 0), x2 = array.get(xpoints, 3), y2 = array.get(ypoints, 3)))
    array.push(centerlines, line.new(x1 = array.get(xpoints, 1), y1 = array.get(ypoints, 1), x2 = array.get(xpoints, 4), y2 = array.get(ypoints, 4)))
    array.push(centerlines, line.new(x1 = array.get(xpoints, 2), y1 = array.get(ypoints, 2), x2 = array.get(xpoints, 5), y2 = array.get(ypoints, 5)))

    points = array.new<chart.point>()
    for x = 0 to 5
        points.push(chart.point.from_index(array.get(pointx, x), array.get(pointy, x)))   

    var polyline pln = na
    polyline.delete(pln)
    pln := polyline.new(points, curved = curved, closed = true, line_color = Rsicolor, line_width = Rsiwidth)

    if circle
        var circles = array.new_label(0)
        for x = 1 to (array.size(circles) > 0 ? array.size(circles) : na)
            label.delete(array.pop(circles))
        for x = 0 to 5
            array.push(circles, label.new(array.get(pointx, x), array.get(pointy, x), style = label.style_circle, size = size.tiny, color = matrix.get(colors, x, 0)))
