Fib RSI++ by [JohnnySnow]
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © jmgneves

// @description 
// RSI++ is an RSI Inspired by my absolutely favorite RSI on tradingview: RSI & EMA with Reverse Calculator Panel [pig] by balipour.
// From it, I reuse balipour implementation for reversing RSI formula in order to calculate price estimation based on Given RSI level (price_by_rsi function lines [43,44,45]).
// Inspired by it, I also combine RSI with a MA but tuned to reads better the support/resistance levels (my opinion).
// This Indicator was built for much quickly identify prices at current RSI and possibly reversals or stops of RSI direction.
// For that,  gridlines based on Fib levels, standard overbought/oversold levels and other levels I personally use were added. All of the grid lines can be configured according to user preferences.
// Display of 2 information tables 
// First with a collection of 'close' numbers and Fib RSI levels price estimations at given RSI
// The second table allows the user to add up to 3 custom RSI levels to further target the price estimation.
// Author UI Preferences to be used with this indicator: dark theme, hidden vertical and horizontal chart gridlines.



//@version=5
indicator(title="Fib RSI++ by [JohnnySnow]", shorttitle="RSI ++", overlay=false)

// # =================== Input Settings ===================== #

rsi_for_price1 = input(100.0, "RSI to Price 1", group = "🟠 Custom RSI Values for price estimation 🟠")
rsi_for_price2 = input(100.0, "RSI To Price 2", group = "🟠 Custom RSI Values for price estimation 🟠")
rsi_for_price3 = input(100.0, "RSI To Price 3", group = "🟠 Custom RSI Values for price estimation 🟠")

src = input(close, "Source", group = "🟠 Input Settings 🟠")
len_rsi = input.int(14, "RSI Length", minval=2, group = "🟠 Input Settings 🟠")
len_ema = input.int(48, "EMA Length", minval=2, group = "🟠 Input Settings 🟠")

show_reference_table = input.bool(defval = true, title = "show RSI to Price reference table" ,group =  "🟠 RSI to Price Tables 🟠" )
show_reference_custom_table = input.bool(defval = true, title = "show custom RSI to Price table", group =  "🟠 RSI to Price Tables 🟠" )
tables_text_size = input.string(defval = "S" , title = "Table text size", options = [ "XS", "S"  , "M" ], group =  "🟠 RSI to Price Tables 🟠"  )
tables_price_trailing_zeros = input.int(defval = 2 , title = "Price trailing zeros", options = [ 1 ,2,3,4,5,6,7,8,9,10 ], group =  "🟠 RSI to Price Tables 🟠" )
tables_transparecy = input.int(defval = 50, title = "Set transparency level for RSI to price tables", group =  "🟠 RSI to Price Tables 🟠" ) 

tables_standard_color = input.color(defval = #9e9e9e, title = "base color for table text",  group =  "🟠 RSI to Price Tables 🟠"  ) 
tables_fib_color = input.color(defval = #ff9800, title = "base color for table text",  group =  "🟠 RSI to Price Tables 🟠"  ) 
tables_custom_color = input.color(defval = #4caf50, title = "base color for table text",  group =  "🟠 RSI to Price Tables 🟠"  ) 


rsi = ta.rsi(src, len_rsi)
ma = ta.ema(rsi, len_ema)
// # =================== Input Settings ===================== #



// # ================== TA Plotting ==================== #
rsi_plot = plot(rsi, "RSI", color=color.new(#ff9800, 0), linewidth=2)
ma_plot = plot(ma, "EMA", color=color.new(#dddddd, 0), style=plot.style_line, linewidth=2)
// # ================== TA Plotting ==================== #



// # ================== RSI Price Tables  ==================== #

price_by_rsi(level) =>
    x1 = (len_rsi - 1) * (ta.rma(math.max(nz(src[1], src) - src, 0), len_rsi) * level / (100 - level) - ta.rma(math.max(src - nz(src[1], src), 0), len_rsi))
    x1 >= 0 ? src + x1 : src + x1 * (100 - level) / level

truncate(number, precision) =>
    factor = math.pow(10, precision)
    int(number * factor) / factor

formatedValue(number) =>
    format = switch tables_price_trailing_zeros
        1 =>str.format("{00,number,#.0}", number)
        2 =>str.format("{00,number,#.00}", number)
        3 =>str.format("{00,number,#.000}", number)
        4 =>str.format("{00,number,#.0000}", number)
        5 =>str.format("{00,number,#.00000}", number)
        6 =>str.format("{00,number,#.000000}", number)
        7 =>str.format("{00,number,#.0000000}", number)
        8 =>str.format("{00,number,#.00000000}", number)
        9 =>str.format("{00,number,#.000000000}", number)
        10 =>str.format("{00,number,#.0000000000}", number)
        =>str.format("{00,number,#.00}", number)

txt_size = switch tables_text_size
    "S" => size.small
    "M" => size.normal
	=> size.tiny

if(show_reference_table)
    tbl = table.new(position.bottom_left, 23, 2)
    table.set_border_width(tbl, 1)
    table.set_border_color(tbl, tables_standard_color)
    table.set_frame_width(tbl, 1)
    table.set_frame_color(tbl, tables_standard_color)

    table.cell(tbl, 0, 0, "RSI", text_color = tables_standard_color,  text_size = txt_size)
    table.cell(tbl, 0, 1, "PRICE", text_color = tables_standard_color,  text_size = txt_size)

    fixed_pe10 = formatedValue(number = price_by_rsi(10))
    table.cell(tbl, 1, 0, "10", text_color = tables_standard_color,  text_size = txt_size)
    table.cell(tbl, 1, 1, fixed_pe10, text_color = tables_standard_color,  text_size = txt_size)

    fixed_pe15 = formatedValue(number = price_by_rsi(15))
    table.cell(tbl, 2, 0, "15", text_color = tables_standard_color,  text_size = txt_size)
    table.cell(tbl, 2, 1, fixed_pe15, text_color = tables_standard_color,  text_size = txt_size)

    fixed_pe20 = formatedValue(number = price_by_rsi(12))
    table.cell(tbl, 3, 0, "20", text_color = tables_standard_color,  text_size = txt_size)
    table.cell(tbl, 3, 1, fixed_pe20, text_color = tables_standard_color,  text_size = txt_size)

    fixed_pe236 = formatedValue(number = price_by_rsi(23.6))
    table.cell(tbl, 4, 0, "23.6", text_color = tables_fib_color,  text_size = txt_size)
    table.cell(tbl, 4, 1, fixed_pe236, text_color = tables_fib_color,  text_size = txt_size)

    fixed_pe25 = formatedValue(number = price_by_rsi(25))
    table.cell(tbl, 5, 0, "25", text_color = tables_standard_color,  text_size = txt_size)
    table.cell(tbl, 5, 1, fixed_pe25, text_color = tables_standard_color,  text_size = txt_size)

    fixed_pe30 = formatedValue(number = price_by_rsi(30))
    table.cell(tbl, 6, 0, "30", text_color = tables_standard_color,  text_size = txt_size)
    table.cell(tbl, 6, 1, fixed_pe30, text_color = tables_standard_color,  text_size = txt_size)

    fixed_pe35 = formatedValue(number = price_by_rsi(35))
    table.cell(tbl, 7, 0, "35", text_color = tables_standard_color,  text_size = txt_size)
    table.cell(tbl, 7, 1, fixed_pe35, text_color = tables_standard_color,  text_size = txt_size)

    fixed_pe382 = formatedValue(number = price_by_rsi(38.2))
    table.cell(tbl, 8, 0, "38.2", text_color = tables_fib_color,  text_size = txt_size)
    table.cell(tbl, 8, 1, fixed_pe382, text_color = tables_fib_color,  text_size = txt_size)

    fixed_pe40 = formatedValue(number = price_by_rsi(40))
    table.cell(tbl, 9, 0, "40", text_color = tables_standard_color,  text_size = txt_size)
    table.cell(tbl, 9, 1, fixed_pe40, text_color = tables_standard_color,  text_size = txt_size)

    fixed_pe45 = formatedValue(number = price_by_rsi(45))
    table.cell(tbl, 10, 0, "45", text_color = tables_standard_color,  text_size = txt_size)
    table.cell(tbl, 10, 1, fixed_pe45, text_color = tables_standard_color,  text_size = txt_size)

    fixed_pe50 = formatedValue(number = price_by_rsi(50))
    table.cell(tbl, 11, 0, "50", text_color = tables_fib_color,  text_size = txt_size)
    table.cell(tbl, 11, 1, fixed_pe50, text_color = tables_fib_color,  text_size = txt_size)

    fixed_pe55 = formatedValue(number = price_by_rsi(55))
    table.cell(tbl, 12, 0, "55", text_color = tables_standard_color,  text_size = txt_size)
    table.cell(tbl, 12, 1, fixed_pe55, text_color = tables_standard_color,  text_size = txt_size)

    fixed_pe60 = formatedValue(number = price_by_rsi(60))
    table.cell(tbl, 13, 0, "60", text_color = tables_standard_color,  text_size = txt_size)
    table.cell(tbl, 13, 1, fixed_pe60, text_color = tables_standard_color,  text_size = txt_size)

    fixed_pe618 = formatedValue(number = price_by_rsi(61.8))
    table.cell(tbl, 14, 0, "61.8", text_color = tables_fib_color,  text_size = txt_size)
    table.cell(tbl, 14, 1, fixed_pe618, text_color = tables_fib_color,  text_size = txt_size)

    fixed_pe65 = formatedValue(number = price_by_rsi(65))
    table.cell(tbl, 15, 0, "65", text_color = tables_standard_color,  text_size = txt_size)
    table.cell(tbl, 15, 1, fixed_pe65, text_color = tables_standard_color,  text_size = txt_size)

    fixed_pe70 = formatedValue(number = price_by_rsi(70))
    table.cell(tbl, 16, 0, "70", text_color = tables_standard_color,  text_size = txt_size)
    table.cell(tbl, 16, 1, fixed_pe70, text_color = tables_standard_color,  text_size = txt_size)

    fixed_pe75 = formatedValue(number = price_by_rsi(75))
    table.cell(tbl, 17, 0, "75", text_color = tables_standard_color,  text_size = txt_size)
    table.cell(tbl, 17, 1, fixed_pe75, text_color = tables_standard_color,  text_size = txt_size)

    fixed_pe786 = formatedValue(number = price_by_rsi(78.6))
    table.cell(tbl, 18, 0, "78.6", text_color = tables_fib_color,  text_size = txt_size)
    table.cell(tbl, 18, 1, fixed_pe786, text_color = tables_fib_color,  text_size = txt_size)

    fixed_pe80 = formatedValue(number = price_by_rsi(80))
    table.cell(tbl, 19, 0, "80", text_color = tables_standard_color,  text_size = txt_size)
    table.cell(tbl, 19, 1, fixed_pe80, text_color = tables_standard_color,  text_size = txt_size)

    fixed_pe85 = formatedValue(number = price_by_rsi(85))
    table.cell(tbl, 20, 0, "85", text_color = tables_standard_color,  text_size = txt_size)
    table.cell(tbl, 20, 1, fixed_pe85, text_color = tables_standard_color,  text_size = txt_size)

    fixed_pe90 = formatedValue(number = price_by_rsi(90))
    table.cell(tbl, 21, 0, "90", text_color = tables_standard_color,  text_size = txt_size)
    table.cell(tbl, 21, 1, fixed_pe90, text_color = tables_standard_color,  text_size = txt_size)


    fixed_pe95 = formatedValue(number = price_by_rsi(95))
    table.cell(tbl, 22, 0, "95", text_color = tables_standard_color,  text_size = txt_size)
    table.cell(tbl, 22, 1, fixed_pe95, text_color = tables_standard_color,  text_size = txt_size)

if(show_reference_custom_table)
    custom_tbl = table.new(position.bottom_right, 3, 2)
    table.set_border_width(custom_tbl, 1)
    table.set_border_color(custom_tbl, tables_standard_color)
    table.set_frame_width(custom_tbl, 1)
    table.set_frame_color(custom_tbl, tables_standard_color)

    fixed_pe1 = formatedValue(number = price_by_rsi(rsi_for_price1))
    table.cell(custom_tbl, 0, 0, formatedValue(number = rsi_for_price1), text_color = tables_custom_color,  text_size = txt_size)
    table.cell(custom_tbl, 0, 1, fixed_pe1, text_color = tables_custom_color,  text_size = txt_size)

    fixed_pe2 = formatedValue(number = price_by_rsi(rsi_for_price2))
    table.cell(custom_tbl, 1, 0, formatedValue(number = rsi_for_price2), text_color = tables_custom_color,  text_size = txt_size)
    table.cell(custom_tbl, 1, 1, fixed_pe2, text_color = tables_custom_color,  text_size = txt_size)

    fixed_pe3 = formatedValue(number = price_by_rsi(rsi_for_price3))
    table.cell(custom_tbl, 2, 0,  formatedValue(number = rsi_for_price3), text_color = tables_custom_color,  text_size = txt_size)
    table.cell(custom_tbl, 2, 1, fixed_pe3, text_color = tables_custom_color,  text_size = txt_size)


// # ================== RSI Price Tables  ==================== #



// # ================== Referencial Zones display ==================== #
fib_lines_transparency = 100
fib_background_transparency = 80
fib_line_color = color.new(#9e9e9e, transp=fib_lines_transparency)
band_line_color = color.new(#9e9e9e, transp=80)


down = hline(23.6,title = "Bottom cloud line (bottom)", linestyle=hline.style_solid, color=fib_line_color)
downGoldenB = hline(35, title = "Bottom cloud line (middle)",linestyle=hline.style_solid, color=fib_line_color)
downGoldenT = hline(38.2, title = "Bottom cloud line (top)",linestyle=hline.style_solid, color=fib_line_color)
upGoldenB = hline(61.8, title = "Upper cloud line (bottom)", linestyle=hline.style_solid, color=fib_line_color)
upGoldenT = hline(65, title = "Upper cloud line (middle)",linestyle=hline.style_solid, color=fib_line_color)
up = hline(78.6, title = "Upper cloud line (top)", linestyle=hline.style_solid, color=fib_line_color)


fill(upGoldenB, upGoldenT, color=#ff9800, transp=fib_background_transparency, title = "Golden overbought background")
fill(downGoldenB, downGoldenT, color=#ff9800, transp=fib_background_transparency, title = "Golden oversold background" )
fill(upGoldenT, up, color=#f44336, transp=fib_background_transparency, title = "Overbought background")
fill(down, downGoldenB, color=#4caf50, transp=fib_background_transparency,title = "Oversold background")


hline(50, title = "Reference line (middle)", linestyle=hline.style_dashed, color=band_line_color)
hline(70, title = "Reference line (overbought)", linestyle=hline.style_dashed, color=band_line_color)
hline(30, title = "Reference line (oversold)", linestyle=hline.style_dashed, color=band_line_color)
hline(85, title = "Reference line (Extreme overbought)", linestyle=hline.style_dashed, color=band_line_color)
hline(20, title = "Reference line (Extreme oversold)", linestyle=hline.style_dashed, color=band_line_color)



upExtremeB = hline(90, title = "Extreme upper cloud line (bottom)", linestyle=hline.style_solid, color=fib_line_color)
upExtremeT = hline(95, title = "Extreme upper cloud line (top)",linestyle=hline.style_solid, color=fib_line_color)
fill(upExtremeT, upExtremeB, color=#b71c1c, transp=fib_background_transparency, title = "Extreme overbought background")

downExtremeB = hline(10, title = " Extreme bottom cloud line (bottom)", linestyle=hline.style_solid, color=fib_line_color)
downExtremeT = hline(15, title = "Extreme bottom cloud line (top)",linestyle=hline.style_solid, color=fib_line_color)
fill(downExtremeB, downExtremeT, color=#1b5e20, transp=fib_background_transparency, title = "Extreme oversold background" )


// # ================== Referencial Zones display ==================== #

