// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © claygrace74
//@version=6
indicator("RSI Window", format=format.percent, overlay=false)
// ==================== Multi-Broker Settings ====================
var multi_broker_group = '========== Combine Stats from Multiple Brokers ========='
broker_1 = input.symbol(title="Broker 1", defval="BINANCE:BTCUSDT", inline="broker_1", group=multi_broker_group)
broker_2 = input.symbol(title="Broker 2", defval="BINANCEUS:BTCUSDT", inline="broker_2", group=multi_broker_group)
broker_3 = input.symbol(title="Broker 3", defval="KUCOIN:BTCUSDT", inline="broker_3", group=multi_broker_group)
broker_4 = input.symbol(title="Broker 4", defval="BITGET:BTCUSDT", inline="broker_4", group=multi_broker_group)
broker_5 = input.symbol(title="Broker 5", defval="BYBIT:BTCUSDT", inline="broker_5", group=multi_broker_group)
bool symbol1 = input.bool(title="Calculate", defval=false, inline="broker_1", group=multi_broker_group)
bool symbol2 = input.bool(title="Calculate", defval=false, inline="broker_2", group=multi_broker_group)
bool symbol3 = input.bool(title="Calculate", defval=false, inline="broker_3", group=multi_broker_group)
bool symbol4 = input.bool(title="Calculate", defval=false, inline="broker_4", group=multi_broker_group)
bool symbol5 = input.bool(title="Calculate", defval=false, inline="broker_5", group=multi_broker_group)
// ==================== RSI Settings ====================
var RSI_group = '============= RSI and Stochastic Settings =============='
rsisrc = input.source(title='RSI Source', defval=close, group=RSI_group)
int rsilen = input.int(title='RSI Length', defval=14, minval=1, group=RSI_group)
rsi_fast_src = input.source(title='Fast RSI Source', defval=close, group=RSI_group)
int rsi_len_fast = input.int(title='Fast RSI Length', defval=5, minval=1, group=RSI_group)
int rsiob = input.int(title='RSI Overbought', defval=70, minval=1, group=RSI_group)
int rsios = input.int(title='RSI Oversold', defval=30, minval=1, group=RSI_group)
// ==================== Display Settings ====================
var disp_group = "Display Settings"
color rsihighclr = input.color(title='OB Color', defval=#FF413B, group=disp_group)
color rsilowclr = input.color(title='OS Color', defval=#00fd7e, group=disp_group)
color rsimidclr = input.color(title='Mid Color', defval=#8AB5FF, group=disp_group)
bool rsi_bg = input.bool(title='RSI colors on chart background', defval=true, group=disp_group)
bool plot_type = input.bool(title='Plot Candles instead of RSI line', defval=false, group=disp_group)
bool i_showFast = input.bool(title='Show Fast RSI', defval=false, group=disp_group)
bool i_showDiv = input.bool(title='Show Divergence Histogram', defval=true, group=disp_group)
bool i_showZoneFill = input.bool(title='Show OB/OS Zone Fills', defval=true, group=disp_group)
// ==================================================================================
// Color Gradient Array (3-segment: cool blue → warm → hot)
// ==================================================================================
var colors = array.new_color()
if barstate.isfirst
for i = 0 to 30
redValue = int(i * 8.5)
array.push(colors, color.rgb(redValue, 200, 255))
for i = 31 to 70
blueValue = int(255 - ((i - 30) * 6.375))
array.push(colors, color.rgb(255, 200, blueValue))
for i = 71 to 100
greenValue = int(255 - (i - 70))
array.push(colors, color.rgb(255, greenValue, 0))
// ==================================================================================
// RSI Calculation Function
// ==================================================================================
f_rsi(_source, _length) =>
rsi_arr = array.new_float(0)
rsi_up_fast = ta.rma(math.max(ta.change(rsi_fast_src), 0), rsi_len_fast)
rsi_down_fast = ta.rma(-math.min(ta.change(rsi_fast_src), 0), rsi_len_fast)
rsi_f = rsi_down_fast == 0 ? 100 : rsi_up_fast == 0 ? 0 : 100 - (100 / (1 + rsi_up_fast / rsi_down_fast))
rsi_up_slow = ta.rma(math.max(ta.change(_source), 0), _length)
rsi_down_slow = ta.rma(-math.min(ta.change(_source), 0), _length)
rsi_s = rsi_down_slow == 0 ? 100 : rsi_up_slow == 0 ? 0 : 100 - (100 / (1 + rsi_up_slow / rsi_down_slow))
array.push(rsi_arr, rsi_f)
array.push(rsi_arr, rsi_s)
rsi_arr
// ==================================================================================
// Multi-Broker RSI Aggregation
// ==================================================================================
brokerage1_rsi_open = symbol1 ? request.security(broker_1, timeframe.period, array.get(f_rsi(open, rsilen), 1)) : na
brokerage2_rsi_open = symbol2 ? request.security(broker_2, timeframe.period, array.get(f_rsi(open, rsilen), 1)) : na
brokerage3_rsi_open = symbol3 ? request.security(broker_3, timeframe.period, array.get(f_rsi(open, rsilen), 1)) : na
brokerage4_rsi_open = symbol4 ? request.security(broker_4, timeframe.period, array.get(f_rsi(open, rsilen), 1)) : na
brokerage5_rsi_open = symbol5 ? request.security(broker_5, timeframe.period, array.get(f_rsi(open, rsilen), 1)) : na
brokerage1_rsi_high = symbol1 ? request.security(broker_1, timeframe.period, array.get(f_rsi(high, rsilen), 1)) : na
brokerage2_rsi_high = symbol2 ? request.security(broker_2, timeframe.period, array.get(f_rsi(high, rsilen), 1)) : na
brokerage3_rsi_high = symbol3 ? request.security(broker_3, timeframe.period, array.get(f_rsi(high, rsilen), 1)) : na
brokerage4_rsi_high = symbol4 ? request.security(broker_4, timeframe.period, array.get(f_rsi(high, rsilen), 1)) : na
brokerage5_rsi_high = symbol5 ? request.security(broker_5, timeframe.period, array.get(f_rsi(high, rsilen), 1)) : na
brokerage1_rsi_low = symbol1 ? request.security(broker_1, timeframe.period, array.get(f_rsi(low, rsilen), 1)) : na
brokerage2_rsi_low = symbol2 ? request.security(broker_2, timeframe.period, array.get(f_rsi(low, rsilen), 1)) : na
brokerage3_rsi_low = symbol3 ? request.security(broker_3, timeframe.period, array.get(f_rsi(low, rsilen), 1)) : na
brokerage4_rsi_low = symbol4 ? request.security(broker_4, timeframe.period, array.get(f_rsi(low, rsilen), 1)) : na
brokerage5_rsi_low = symbol5 ? request.security(broker_5, timeframe.period, array.get(f_rsi(low, rsilen), 1)) : na
brokerage1_rsi_close = symbol1 ? request.security(broker_1, timeframe.period, array.get(f_rsi(close, rsilen), 1)) : na
brokerage2_rsi_close = symbol2 ? request.security(broker_2, timeframe.period, array.get(f_rsi(close, rsilen), 1)) : na
brokerage3_rsi_close = symbol3 ? request.security(broker_3, timeframe.period, array.get(f_rsi(close, rsilen), 1)) : na
brokerage4_rsi_close = symbol4 ? request.security(broker_4, timeframe.period, array.get(f_rsi(close, rsilen), 1)) : na
brokerage5_rsi_close = symbol5 ? request.security(broker_5, timeframe.period, array.get(f_rsi(close, rsilen), 1)) : na
combined_rsi_open = 0.0
combined_rsi_high = 0.0
combined_rsi_low = 0.0
combined_rsi_close = 0.0
symCount = 0
if symbol1
combined_rsi_open += brokerage1_rsi_open, combined_rsi_high += brokerage1_rsi_high
combined_rsi_low += brokerage1_rsi_low, combined_rsi_close += brokerage1_rsi_close, symCount += 1
if symbol2
combined_rsi_open += brokerage2_rsi_open, combined_rsi_high += brokerage2_rsi_high
combined_rsi_low += brokerage2_rsi_low, combined_rsi_close += brokerage2_rsi_close, symCount += 1
if symbol3
combined_rsi_open += brokerage3_rsi_open, combined_rsi_high += brokerage3_rsi_high
combined_rsi_low += brokerage3_rsi_low, combined_rsi_close += brokerage3_rsi_close, symCount += 1
if symbol4
combined_rsi_open += brokerage4_rsi_open, combined_rsi_high += brokerage4_rsi_high
combined_rsi_low += brokerage4_rsi_low, combined_rsi_close += brokerage4_rsi_close, symCount += 1
if symbol5
combined_rsi_open += brokerage5_rsi_open, combined_rsi_high += brokerage5_rsi_high
combined_rsi_low += brokerage5_rsi_low, combined_rsi_close += brokerage5_rsi_close, symCount += 1
if symCount > 0
combined_rsi_open /= symCount, combined_rsi_high /= symCount
combined_rsi_low /= symCount, combined_rsi_close /= symCount
combined_rsi_val = rsisrc == open ? combined_rsi_open : rsisrc == high ? combined_rsi_high : rsisrc == low ? combined_rsi_low : rsisrc == close ? combined_rsi_close : rsisrc == hl2 ? ((combined_rsi_high + combined_rsi_low) / 2) : rsisrc == hlc3 ? ((combined_rsi_high + combined_rsi_low + combined_rsi_close) / 3) : rsisrc == hlcc4 ? ((combined_rsi_high + combined_rsi_low + combined_rsi_close + combined_rsi_close) / 4) : rsisrc == ohlc4 ? ((combined_rsi_open + combined_rsi_high + combined_rsi_low + combined_rsi_close) / 4) : na
// ==================================================================================
// Local RSI Calculation
// ==================================================================================
local_rsi_open = array.get(f_rsi(open, rsilen), 1)
local_rsi_high = array.get(f_rsi(high, rsilen), 1)
local_rsi_low = array.get(f_rsi(low, rsilen), 1)
local_rsi_close = array.get(f_rsi(close, rsilen), 1)
rsi_open = plot_type and combined_rsi_open > 0 ? ((combined_rsi_open + local_rsi_open) / 2) : local_rsi_open
rsi_high = plot_type and combined_rsi_high > 0 ? ((combined_rsi_high + local_rsi_high) / 2) : local_rsi_high
rsi_low = plot_type and combined_rsi_low > 0 ? ((combined_rsi_low + local_rsi_low) / 2) : local_rsi_low
rsi_close = plot_type and combined_rsi_close > 0 ? ((combined_rsi_close + local_rsi_close) / 2) : local_rsi_close
rsiArr = f_rsi(rsisrc, rsilen)
rsi_fast = array.get(rsiArr, 0)
rsi_slow = array.get(rsiArr, 1)
divergence = (rsi_fast - rsi_slow) + 50
useBrokers = symbol1 or symbol2 or symbol3 or symbol4 or symbol5
rsival = useBrokers ? (rsi_slow + combined_rsi_val) / 2 : rsi_slow
is_rsi_ob = rsival >= rsiob
is_rsi_os = rsival <= rsios
// Gradient background color
rsiclr = array.get(colors, math.min(math.max(math.round(rsival), 0), 100))
bgcolor(rsi_bg ? rsiclr : na)
// Cross signals
obCross = ta.crossover(rsival, rsiob)
osCross = ta.crossunder(rsival, rsios)
obExit = ta.crossunder(rsival, rsiob)
osExit = ta.crossover(rsival, rsios)
display_candles = plot_type ? display.all : display.none
display_line = plot_type ? display.none : display.all
rsi_div_color = rsi_fast > rsi_slow ? color.rgb(0, 238, 71) : color.rgb(255, 8, 0)
candleColor = rsi_close > rsi_open ? color.green : color.red
// ==================================================================================
// Grid Layout
// ==================================================================================
h100 = hline(100, "100", color=color.new(color.gray, 80))
hOB = hline(rsiob, "Overbought", color=color.new(#787B86, 50))
hMid = hline(50, "Midline", color=color.new(#787B86, 50))
hOS = hline(rsios, "Oversold", color=color.new(#787B86, 50))
h0 = hline(0, "0", color=color.new(color.gray, 80))
// Zone fills
fill(hOB, h100, color=i_showZoneFill ? color.new(rsihighclr, 90) : color(na), title="OB Zone")
fill(h0, hOS, color=i_showZoneFill ? color.new(rsilowclr, 90) : color(na), title="OS Zone")
// ==================================================================================
// Plots
// ==================================================================================
plot(i_showDiv ? divergence : na, title='Divergence', linewidth=1, style=plot.style_columns, color=rsi_div_color, histbase=50)
plot(rsival, title='RSI', linewidth=2, style=plot.style_line, color=color.rgb(37, 95, 255), display=display_line)
plot(i_showFast ? rsi_fast : na, title='RSI Fast', linewidth=1, style=plot.style_line, color=color.rgb(9, 0, 133))
plotcandle(rsi_open, rsi_high, rsi_low, rsi_close, title="RSI Candles", color=candleColor, display=display_candles)
// OB/OS cross signals
plotshape(obCross, style=shape.triangledown, location=location.top, color=rsihighclr, text="OB", textcolor=rsihighclr, size=size.tiny, title="Entered OB")
plotshape(osExit, style=shape.triangleup, location=location.bottom, color=rsilowclr, text="OS Exit", textcolor=rsilowclr, size=size.tiny, title="Exited OS")
// Current RSI price line
var line ln = na
line.delete(ln[1])
ln := line.new(bar_index - 1, rsi_close, bar_index, rsi_close, width=1, color=candleColor, extend=extend.both, style=line.style_dotted)
// ==================================================================================
// Alert Conditions
// ==================================================================================
alertcondition(obCross, "RSI Entered Overbought", "RSI crossed above overbought level")
alertcondition(osCross, "RSI Entered Oversold", "RSI crossed below oversold level")
alertcondition(obExit, "RSI Exited Overbought", "RSI crossed back below overbought level")
alertcondition(osExit, "RSI Exited Oversold", "RSI crossed back above oversold level")
alertcondition(ta.crossover(rsival, 50), "RSI Above 50", "RSI crossed above midline — bullish momentum")
alertcondition(ta.crossunder(rsival, 50), "RSI Below 50", "RSI crossed below midline — bearish momentum")
Show all 202 lines