PROTECTED SOURCE SCRIPT
RSI + BB + RSI Advanced MTF Panel

//version=6
indicator(title="RSI + BB + RSI Advanced MTF Panel", shorttitle="RSI + BB + RSI Advance MTF Panel", format=format.price, precision=2, overlay=false)
bb_group = "BB (Price Overlay)"
bb_length = input.int(50, minval=1, group = bb_group)
bb_maType = input.string("SMA", "Basis MA Type", options = ["SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group = bb_group)
bb_src = input.source(close, title="Source", group = bb_group)
bb_mult = input.float(0.2, minval=0.001, maxval=50, title="StdDev", group = bb_group)
BasisColor = input.color(color.rgb(163, 41, 245), "Basis Color", group = bb_group, display = display.none)
UpperColor = input.color(color.rgb(120, 156, 202,100), "Upper Color", group = bb_group, display = display.none)
LowerColor = input.color(color.rgb(120, 156, 202,100), "Lower Color", group = bb_group, display = display.none)
offset = input.int(0, "Offset", minval = -500, maxval = 500, display = display.data_window, group = bb_group)
ma(source, bb_length, _type) =>
switch _type
"SMA" => ta.sma(source, bb_length)
"EMA" => ta.ema(source, bb_length)
"SMMA (RMA)" => ta.rma(source, bb_length)
"WMA" => ta.wma(source, bb_length)
"VWMA" => ta.vwma(source, bb_length)
basis = ma(bb_src, bb_length, bb_maType)
dev = bb_mult * ta.stdev(bb_src, bb_length)
upper = basis + dev
lower = basis - dev
plot(basis, "Basis", color=BasisColor, offset = offset, force_overlay = true)
p1 = plot(upper, "Upper", color=UpperColor, offset = offset, force_overlay = true)
p2 = plot(lower, "Lower", color=LowerColor, offset = offset, force_overlay = true)
fill(p1, p2, title = "Background", color=color.rgb(163, 41, 245, 90))
rsiLengthInput = input.int(30, minval=1, title="RSI Length", group="RSI Settings")
rsiSourceInput = input.source(close, "Source", group="RSI Settings")
calculateDivergence = input.bool(false, title="Calculate Divergence", group="RSI Settings", display = display.data_window, tooltip = "Calculating divergences is needed in order for divergence alerts to fire.")
SignalDot = input.bool(false, title="Signal Dot", group="Smoothing", display = display.data_window, tooltip = "Signal for possible entry")
change = ta.change(rsiSourceInput)
up = ta.rma(math.max(change, 0), rsiLengthInput)
down = ta.rma(-math.min(change, 0), rsiLengthInput)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
rsiPlot = plot(rsi, "RSI", color= rsi >= 51 ? color.rgb(13, 197, 230) : color.red)
rsiUpperBand = hline(70, "RSI Upper Band", color=#787B86)
midline = hline(50, "RSI Middle Band", color=color.new(#787B86, 50))
rsiLowerBand = hline(30, "RSI Lower Band", color=#787B86)
fill(rsiUpperBand, rsiLowerBand, color=color.rgb(126, 87, 194, 90), title="RSI Background Fill")
midLinePlot = plot(50, color = na, editable = false, display = display.none)
fill(rsiPlot, midLinePlot, 100, 70, top_color = color.new(color.green, 0), bottom_color = color.new(color.green, 100), title = "Overbought Gradient Fill")
fill(rsiPlot, midLinePlot, 30, 0, top_color = color.new(color.red, 100), bottom_color = color.new(color.red, 0), title = "Oversold Gradient Fill")
GRP = "Smoothing"
TT_BB = "Only applies when 'SMA + Bollinger Bands' is selected. Determines the distance between the SMA and the bands."
maTypeInput = input.string("SMA", "Type", options = ["None", "SMA", "SMA + Bollinger Bands", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group = GRP, display = display.data_window)
maLengthInput = input.int(14, "Length", group = GRP, display = display.data_window)
bbMultInput = input.float(2.0, "BB StdDev", minval = 0.001, maxval = 50, step = 0.5, tooltip = TT_BB, group = GRP, display = display.data_window)
var enableMA = maTypeInput != "None"
var isBB = maTypeInput == "SMA + Bollinger Bands"
smoothma(source, length, MAtype) =>
switch MAtype
"SMA" => ta.sma(source, length)
"SMA + Bollinger Bands" => ta.sma(source, length)
"EMA" => ta.ema(source, length)
"SMMA (RMA)" => ta.rma(source, length)
"WMA" => ta.wma(source, length)
"VWMA" => ta.vwma(source, length)
smoothingMA = enableMA ? smoothma(rsi, maLengthInput, maTypeInput) : na
smoothingStDev = isBB ? ta.stdev(rsi, maLengthInput) * bbMultInput : na
plot(smoothingMA, "RSI-based MA", color=color.yellow, display = enableMA ? display.all : display.none, editable = enableMA)
bbUpperBand = plot(smoothingMA + smoothingStDev, title = "Upper Bollinger Band", color=color.green, display = isBB ? display.all : display.none, editable = isBB)
bbLowerBand = plot(smoothingMA - smoothingStDev, title = "Lower Bollinger Band", color=color.green, display = isBB ? display.all : display.none, editable = isBB)
fill(bbUpperBand, bbLowerBand, color= isBB ? color.new(color.green, 90) : na, title="Bollinger Bands Background Fill", display = isBB ? display.all : display.none, editable = isBB)
lookbackRight = 5
lookbackLeft = 5
rangeUpper = 60
rangeLower = 5
bearColor = color.red
bullColor = color.green
textColor = color.white
noneColor = color.new(color.white, 100)
_calcBarsSince(cond) =>
ta.barssince(cond)
rsiLBR = rsi[lookbackRight]
// 1. Calculate Pivots Unconditionally
plFound = not na(ta.pivotlow(rsi, lookbackLeft, lookbackRight))
phFound = not na(ta.pivothigh(rsi, lookbackLeft, lookbackRight))
// 2. Calculate History Unconditionally
barsSincePL = _calcBarsSince(plFound[1])
barsSincePH = _calcBarsSince(phFound[1])
// 3. Check Ranges Unconditionally
inRangePL = rangeLower <= barsSincePL and barsSincePL <= rangeUpper
inRangePH = rangeLower <= barsSincePH and barsSincePH <= rangeUpper
// 4. Calculate Conditions
var bool bullCond = false
var bool bearCond = false
if calculateDivergence
rsiHL = rsiLBR > ta.valuewhen(plFound, rsiLBR, 1) and inRangePL
lowLBR = low[lookbackRight]
priceLL = lowLBR < ta.valuewhen(plFound, lowLBR, 1)
bullCond := priceLL and rsiHL and plFound
rsiLH = rsiLBR < ta.valuewhen(phFound, rsiLBR, 1) and inRangePH
highLBR = high[lookbackRight]
priceHH = highLBR > ta.valuewhen(phFound, highLBR, 1)
bearCond := priceHH and rsiLH and phFound
else
bullCond := false
bearCond := false
plot(plFound ? rsiLBR : na, offset = -lookbackRight, title = "Regular Bullish", linewidth = 2, color = (bullCond ? bullColor : noneColor), display = display.pane, editable = calculateDivergence)
plotshape(bullCond ? rsiLBR : na, offset = -lookbackRight, title = "Regular Bullish Label", text = " Bull ", style = shape.labelup, location = location.absolute, color = bullColor, textcolor = textColor, display = display.pane, editable = calculateDivergence)
plot(phFound ? rsiLBR : na, offset = -lookbackRight, title = "Regular Bearish", linewidth = 2, color = (bearCond ? bearColor : noneColor), display = display.pane, editable = calculateDivergence)
plotshape(bearCond ? rsiLBR : na, offset = -lookbackRight, title = "Regular Bearish Label", text = " Bear ", style = shape.labeldown, location = location.absolute, color = bearColor, textcolor = textColor, display = display.pane, editable = calculateDivergence)
alertcondition(bullCond, title='Regular Bullish Divergence', message="Found a new Regular Bullish Divergence.")
alertcondition(bearCond, title='Regular Bearish Divergence', message='Found a new Regular Bearish Divergence.')
// --- Panel Options (General) ---
g_panel = 'MTF Panel Options'
i_orientation = input.string('Vertical', 'Orientation', options = ['Vertical', 'Horizontal'], group = g_panel)
i_position = input.string('Bottom Right', 'Position', options = ['Top Left', 'Top Right', 'Top Center', 'Bottom Left', 'Bottom Right', 'Bottom Center', 'Middle Left', 'Middle Right', 'Middle Center'], group = g_panel)
i_border_width = input.int(1, 'Border Width', minval = 0, maxval = 10, group = g_panel, inline = 'border')
i_color_border = input.color(#000000, '', group = g_panel, inline = 'border')
i_showHeaders = input.bool(true, 'Show Headers', group = g_panel)
i_color_header_bg = input.color(#5d606b, 'Headers Background', group = g_panel, inline = 'header')
i_color_header_text = input.color(color.white, 'Text', group = g_panel, inline = 'header')
i_color_tf_bg = input.color(#2a2e39, 'Timeframe Background', group = g_panel, inline = 'tf')
i_color_tf_text = input.color(color.white, 'Text', group = g_panel, inline = 'tf')
i_debug = input.bool(false, 'Display colors palette (debug)', group = g_panel)
// --- RSI Colors (Conditional Formatting) ---
g_rsi = 'MTF RSI Colors'
i_threshold_ob = input.int(70, 'Overbought Threshold', minval=51, maxval=100, group = g_rsi)
i_color_ob = input.color(#128416, 'Overbought Background', inline = 'ob', group = g_rsi)
i_tcolor_ob = input.color(color.white, 'Text', inline = 'ob', group = g_rsi)
i_threshold_uptrend = input.int(60, 'Uptrend Threshold', minval=51, maxval=100, group = g_rsi)
i_color_uptrend = input.color(#2d472e, 'Uptrend Background', inline = 'up', group = g_rsi)
i_tcolor_uptrend = input.color(color.white, 'Text', inline = 'up', group = g_rsi)
i_color_mid = input.color(#131722, 'No Trend Background', group = g_rsi, inline = 'mid')
i_tcolor_mid = input.color(#b2b5be, 'Text', group = g_rsi, inline = 'mid')
i_threshold_downtrend = input.int(40, 'Downtrend Threshold', group = g_rsi, minval=0, maxval=49)
i_color_downtrend = input.color(#5b2e2e, 'Downtrend Background', group = g_rsi, inline = 'down')
i_tcolor_downtrend = input.color(color.white, 'Text', group = g_rsi, inline = 'down')
i_threshold_os = input.int(30, 'Oversold Threshold', minval=0, maxval=49, group = g_rsi)
i_color_os = input.color(#db3240, 'Oversold Background', group = g_rsi, inline = 'os')
i_tcolor_os = input.color(color.white, 'Text', group = g_rsi, inline = 'os')
// --- Individual RSI Settings (MTF Sources) ---
g_rsi1 = 'RSI #1'
i_rsi1_enabled = input.bool(true, title = 'Enabled', group = g_rsi1)
i_rsi1_tf = input.timeframe('5', 'Timeframe', group = g_rsi1)
i_rsi1_len = input.int(30, 'Length', minval = 1, group = g_rsi1)
i_rsi1_src = input.source(close, 'Source', group = g_rsi1) * 10000
v_rsi1 = i_rsi1_enabled ? request.security(syminfo.tickerid, i_rsi1_tf, ta.rsi(i_rsi1_src, i_rsi1_len)) : na
g_rsi2 = 'RSI #2'
i_rsi2_enabled = input.bool(true, title = 'Enabled', group = g_rsi2)
i_rsi2_tf = input.timeframe('15', 'Timeframe', group = g_rsi2)
i_rsi2_len = input.int(30, 'Length', minval = 1, group = g_rsi2)
i_rsi2_src = input.source(close, 'Source', group = g_rsi2) * 10000
v_rsi2 = i_rsi2_enabled ? request.security(syminfo.tickerid, i_rsi2_tf, ta.rsi(i_rsi2_src, i_rsi2_len)) : na
g_rsi3 = 'RSI #3'
i_rsi3_enabled = input.bool(true, title = 'Enabled', group = g_rsi3)
i_rsi3_tf = input.timeframe('60', 'Timeframe', group = g_rsi3)
i_rsi3_len = input.int(30, 'Length', minval = 1, group = g_rsi3)
i_rsi3_src = input.source(close, 'Source', group = g_rsi3) * 10000
v_rsi3 = i_rsi3_enabled ? request.security(syminfo.tickerid, i_rsi3_tf, ta.rsi(i_rsi3_src, i_rsi3_len)) : na
g_rsi4 = 'RSI #4'
i_rsi4_enabled = input.bool(true, title = 'Enabled', group = g_rsi4)
i_rsi4_tf = input.timeframe('240', 'Timeframe', group = g_rsi4)
i_rsi4_len = input.int(30, 'Length', minval = 1, group = g_rsi4)
i_rsi4_src = input.source(close, 'Source', group = g_rsi4) * 10000
v_rsi4 = i_rsi4_enabled ? request.security(syminfo.tickerid, i_rsi4_tf, ta.rsi(i_rsi4_src, i_rsi4_len)) : na
g_rsi5 = 'RSI #5'
i_rsi5_enabled = input.bool(true, title = 'Enabled', group = g_rsi5)
i_rsi5_tf = input.timeframe('D', 'Timeframe', group = g_rsi5)
i_rsi5_len = input.int(30, 'Length', minval = 1, group = g_rsi5)
i_rsi5_src = input.source(close, 'Source', group = g_rsi5) * 10000
v_rsi5 = i_rsi5_enabled ? request.security(syminfo.tickerid, i_rsi5_tf, ta.rsi(i_rsi5_src, i_rsi5_len)) : na
g_rsi6 = 'RSI #6'
i_rsi6_enabled = input.bool(true, title = 'Enabled', group = g_rsi6)
i_rsi6_tf = input.timeframe('W', 'Timeframe', group = g_rsi6)
i_rsi6_len = input.int(30, 'Length', minval = 1, group = g_rsi6)
i_rsi6_src = input.source(close, 'Source', group = g_rsi6) * 10000
v_rsi6 = i_rsi6_enabled ? request.security(syminfo.tickerid, i_rsi6_tf, ta.rsi(i_rsi6_src, i_rsi6_len)) : na
g_rsi7 = 'RSI #7'
i_rsi7_enabled = input.bool(false, title = 'Enabled', group = g_rsi7)
i_rsi7_tf = input.timeframe('W', 'Timeframe', group = g_rsi7)
i_rsi7_len = input.int(30, 'Length', minval = 1, group = g_rsi7)
i_rsi7_src = input.source(close, 'Source', group = g_rsi7) * 10000
v_rsi7 = i_rsi7_enabled ? request.security(syminfo.tickerid, i_rsi7_tf, ta.rsi(i_rsi7_src, i_rsi7_len)) : na
g_rsi8 = 'RSI #8'
i_rsi8_enabled = input.bool(false, title = 'Enabled', group = g_rsi8)
i_rsi8_tf = input.timeframe('W', 'Timeframe', group = g_rsi8)
i_rsi8_len = input.int(30, 'Length', minval = 1, group = g_rsi8)
i_rsi8_src = input.source(close, 'Source', group = g_rsi8) * 10000
v_rsi8 = i_rsi8_enabled ? request.security(syminfo.tickerid, i_rsi8_tf, ta.rsi(i_rsi8_src, i_rsi8_len)) : na
g_rsi9 = 'RSI #9'
i_rsi9_enabled = input.bool(false, title = 'Enabled', group = g_rsi9)
i_rsi9_tf = input.timeframe('W', 'Timeframe', group = g_rsi9)
i_rsi9_len = input.int(30, 'Length', minval = 1, group = g_rsi9)
i_rsi9_src = input.source(close, 'Source', group = g_rsi9) * 10000
v_rsi9 = i_rsi9_enabled ? request.security(syminfo.tickerid, i_rsi9_tf, ta.rsi(i_rsi9_src, i_rsi9_len)) : na
g_rsi10 = 'RSI #10'
i_rsi10_enabled = input.bool(false, title = 'Enabled', group = g_rsi10)
i_rsi10_tf = input.timeframe('W', 'Timeframe', group = g_rsi10)
i_rsi10_len = input.int(30, 'Length', minval = 1, group = g_rsi10)
i_rsi10_src = input.source(close, 'Source', group = g_rsi10) * 10000
v_rsi10 = i_rsi10_enabled ? request.security(syminfo.tickerid, i_rsi10_tf, ta.rsi(i_rsi10_src, i_rsi10_len)) : na
// --- Panel Helper Functions ---
// Function 4: String Position to Constant (Indentation cleaned)
f_StrPositionToConst(_p) =>
switch _p
'Top Left' => position.top_left
'Top Right' => position.top_right
'Top Center' => position.top_center
'Middle Left' => position.middle_left
'Middle Right' => position.middle_right
'Middle Center' => position.middle_center
'Bottom Left' => position.bottom_left
'Bottom Right' => position.bottom_right
'Bottom Center' => position.bottom_center
=> position.bottom_right
// Function 5: Timeframe to Human Readable (Indentation cleaned)
f_timeframeToHuman(_tf) =>
seconds = timeframe.in_seconds(_tf)
if seconds < 60
_tf
else if seconds < 3600
str.tostring(seconds / 60) + 'm'
else if seconds < 86400
str.tostring(seconds / 60 / 60) + 'h'
else
switch _tf
"1D" => "D"
"1W" => "W"
"1M" => "M"
=> str.tostring(_tf)
type TPanel
table src = na
bool vertical_orientation = true
int row = 0
int col = 0
// Method 1: Increment Column (Indentation cleaned)
method incCol(TPanel _panel) =>
if _panel.vertical_orientation
_panel.col += 1
else
_panel.row += 1
// Method 2: Increment Row (Indentation cleaned)
method incRow(TPanel _panel) =>
if not _panel.vertical_orientation
_panel.col += 1
_panel.row := 0
else
_panel.row += 1
_panel.col := 0
// Method 3: Add Cell (Indentation cleaned)
method add(TPanel _panel, string _v1, color _bg1, color _ctext1, string _v2, color _bg2, color _ctext2) =>
table.cell(_panel.src, _panel.col, _panel.row, _v1, text_color = _ctext1, bgcolor = _bg1)
_panel.incCol()
table.cell(_panel.src, _panel.col, _panel.row, _v2, text_color = _ctext2, bgcolor = _bg2)
_panel.incRow()
// Function 6: Background Color
f_bg(_rsi) =>
c_line = na(_rsi) ? i_color_mid :
_rsi >= i_threshold_ob ? i_color_ob :
_rsi >= i_threshold_uptrend ? i_color_uptrend :
_rsi <= i_threshold_os ? i_color_os :
_rsi <= i_threshold_downtrend ? i_color_downtrend :
i_color_mid
// Function 7: Text Color
f_rsi_text_color(_rsi) =>
c_line = na(_rsi) ? i_tcolor_mid :
_rsi >= i_threshold_ob ? i_tcolor_ob :
_rsi >= i_threshold_uptrend ? i_tcolor_uptrend :
_rsi <= i_threshold_os ? i_tcolor_os :
_rsi <= i_threshold_downtrend ? i_tcolor_downtrend :
i_tcolor_mid
f_formatRsi(_rsi) => na(_rsi) ? 'N/A' : str.tostring(_rsi, '0.00')
// --- Panel Execution Logic ---
if barstate.islast
v_panel = TPanel.new(vertical_orientation = i_orientation == 'Vertical')
v_max_rows = 20
v_panel.src := table.new(f_StrPositionToConst(i_position), v_max_rows, v_max_rows, border_width = i_border_width, border_color = i_color_border)
if i_showHeaders
v_panel.add('TF', i_color_header_bg, i_color_header_text, 'RSI', i_color_header_bg, i_color_header_text)
if i_rsi1_enabled
v_panel.add(f_timeframeToHuman(i_rsi1_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi1), f_bg(v_rsi1), f_rsi_text_color(v_rsi1))
if i_rsi2_enabled
v_panel.add(f_timeframeToHuman(i_rsi2_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi2), f_bg(v_rsi2), f_rsi_text_color(v_rsi2))
if i_rsi3_enabled
v_panel.add(f_timeframeToHuman(i_rsi3_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi3), f_bg(v_rsi3), f_rsi_text_color(v_rsi3))
if i_rsi4_enabled
v_panel.add(f_timeframeToHuman(i_rsi4_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi4), f_bg(v_rsi4), f_rsi_text_color(v_rsi4))
if i_rsi5_enabled
v_panel.add(f_timeframeToHuman(i_rsi5_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi5), f_bg(v_rsi5), f_rsi_text_color(v_rsi5))
if i_rsi6_enabled
v_panel.add(f_timeframeToHuman(i_rsi6_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi6), f_bg(v_rsi6), f_rsi_text_color(v_rsi6))
if i_rsi7_enabled
v_panel.add(f_timeframeToHuman(i_rsi7_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi7), f_bg(v_rsi7), f_rsi_text_color(v_rsi7))
if i_rsi8_enabled
v_panel.add(f_timeframeToHuman(i_rsi8_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi8), f_bg(v_rsi8), f_rsi_text_color(v_rsi8))
if i_rsi9_enabled
v_panel.add(f_timeframeToHuman(i_rsi9_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi9), f_bg(v_rsi9), f_rsi_text_color(v_rsi9))
if i_rsi10_enabled
v_panel.add(f_timeframeToHuman(i_rsi10_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi10), f_bg(v_rsi10), f_rsi_text_color(v_rsi10))
if i_debug
t = table.new(position.middle_center, 21, 20, border_width = i_border_width, border_color = i_color_border)
v_panel2 = TPanel.new(t, vertical_orientation = i_orientation == 'Vertical')
v_panel2.add('Debug', i_color_header_bg, i_color_header_text, 'Colors', i_color_header_bg, i_color_header_text)
// Using a tuple array for debugging colors demo
// Final Syntax Correction: Use array.new<string>() and array.set() to avoid 'tuple()' function reference error
v_rows = 5 // We know we have 5 elements
demo = array.new<string>(v_rows, '') // Initialize array with 5 string elements, will hold string representation of the tuple
// We will push the elements as a *string* representation of the tuple, as Pine v6 allows
// and then parse them inside the loop if necessary.
// To preserve the structure (string, float) without the tuple() function:
// We must define two separate arrays if the 'tuple' function is truly unavailable.
tf_array = array.new<string>(v_rows)
rsi_array = array.new<float>(v_rows)
// Populate the arrays
array.set(tf_array, 0, 'Overbought')
array.set(rsi_array, 0, float(i_threshold_ob))
array.set(tf_array, 1, 'Uptrend')
array.set(rsi_array, 1, float(i_threshold_uptrend))
array.set(tf_array, 2, 'No Trend')
array.set(rsi_array, 2, 50.0)
array.set(tf_array, 3, 'Downtrend')
array.set(rsi_array, 3, float(i_threshold_downtrend))
array.set(tf_array, 4, 'Oversold')
array.set(rsi_array, 4, float(i_threshold_os))
// Iterate over the arrays using a simple index
for i = 0 to v_rows - 1
tf = array.get(tf_array, i)
rsi = array.get(rsi_array, i)
v_panel2.add(tf, i_color_tf_bg, i_color_tf_text, f_formatRsi(rsi), f_bg(rsi), f_rsi_text_color(rsi))
indicator(title="RSI + BB + RSI Advanced MTF Panel", shorttitle="RSI + BB + RSI Advance MTF Panel", format=format.price, precision=2, overlay=false)
bb_group = "BB (Price Overlay)"
bb_length = input.int(50, minval=1, group = bb_group)
bb_maType = input.string("SMA", "Basis MA Type", options = ["SMA", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group = bb_group)
bb_src = input.source(close, title="Source", group = bb_group)
bb_mult = input.float(0.2, minval=0.001, maxval=50, title="StdDev", group = bb_group)
BasisColor = input.color(color.rgb(163, 41, 245), "Basis Color", group = bb_group, display = display.none)
UpperColor = input.color(color.rgb(120, 156, 202,100), "Upper Color", group = bb_group, display = display.none)
LowerColor = input.color(color.rgb(120, 156, 202,100), "Lower Color", group = bb_group, display = display.none)
offset = input.int(0, "Offset", minval = -500, maxval = 500, display = display.data_window, group = bb_group)
ma(source, bb_length, _type) =>
switch _type
"SMA" => ta.sma(source, bb_length)
"EMA" => ta.ema(source, bb_length)
"SMMA (RMA)" => ta.rma(source, bb_length)
"WMA" => ta.wma(source, bb_length)
"VWMA" => ta.vwma(source, bb_length)
basis = ma(bb_src, bb_length, bb_maType)
dev = bb_mult * ta.stdev(bb_src, bb_length)
upper = basis + dev
lower = basis - dev
plot(basis, "Basis", color=BasisColor, offset = offset, force_overlay = true)
p1 = plot(upper, "Upper", color=UpperColor, offset = offset, force_overlay = true)
p2 = plot(lower, "Lower", color=LowerColor, offset = offset, force_overlay = true)
fill(p1, p2, title = "Background", color=color.rgb(163, 41, 245, 90))
rsiLengthInput = input.int(30, minval=1, title="RSI Length", group="RSI Settings")
rsiSourceInput = input.source(close, "Source", group="RSI Settings")
calculateDivergence = input.bool(false, title="Calculate Divergence", group="RSI Settings", display = display.data_window, tooltip = "Calculating divergences is needed in order for divergence alerts to fire.")
SignalDot = input.bool(false, title="Signal Dot", group="Smoothing", display = display.data_window, tooltip = "Signal for possible entry")
change = ta.change(rsiSourceInput)
up = ta.rma(math.max(change, 0), rsiLengthInput)
down = ta.rma(-math.min(change, 0), rsiLengthInput)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
rsiPlot = plot(rsi, "RSI", color= rsi >= 51 ? color.rgb(13, 197, 230) : color.red)
rsiUpperBand = hline(70, "RSI Upper Band", color=#787B86)
midline = hline(50, "RSI Middle Band", color=color.new(#787B86, 50))
rsiLowerBand = hline(30, "RSI Lower Band", color=#787B86)
fill(rsiUpperBand, rsiLowerBand, color=color.rgb(126, 87, 194, 90), title="RSI Background Fill")
midLinePlot = plot(50, color = na, editable = false, display = display.none)
fill(rsiPlot, midLinePlot, 100, 70, top_color = color.new(color.green, 0), bottom_color = color.new(color.green, 100), title = "Overbought Gradient Fill")
fill(rsiPlot, midLinePlot, 30, 0, top_color = color.new(color.red, 100), bottom_color = color.new(color.red, 0), title = "Oversold Gradient Fill")
GRP = "Smoothing"
TT_BB = "Only applies when 'SMA + Bollinger Bands' is selected. Determines the distance between the SMA and the bands."
maTypeInput = input.string("SMA", "Type", options = ["None", "SMA", "SMA + Bollinger Bands", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group = GRP, display = display.data_window)
maLengthInput = input.int(14, "Length", group = GRP, display = display.data_window)
bbMultInput = input.float(2.0, "BB StdDev", minval = 0.001, maxval = 50, step = 0.5, tooltip = TT_BB, group = GRP, display = display.data_window)
var enableMA = maTypeInput != "None"
var isBB = maTypeInput == "SMA + Bollinger Bands"
smoothma(source, length, MAtype) =>
switch MAtype
"SMA" => ta.sma(source, length)
"SMA + Bollinger Bands" => ta.sma(source, length)
"EMA" => ta.ema(source, length)
"SMMA (RMA)" => ta.rma(source, length)
"WMA" => ta.wma(source, length)
"VWMA" => ta.vwma(source, length)
smoothingMA = enableMA ? smoothma(rsi, maLengthInput, maTypeInput) : na
smoothingStDev = isBB ? ta.stdev(rsi, maLengthInput) * bbMultInput : na
plot(smoothingMA, "RSI-based MA", color=color.yellow, display = enableMA ? display.all : display.none, editable = enableMA)
bbUpperBand = plot(smoothingMA + smoothingStDev, title = "Upper Bollinger Band", color=color.green, display = isBB ? display.all : display.none, editable = isBB)
bbLowerBand = plot(smoothingMA - smoothingStDev, title = "Lower Bollinger Band", color=color.green, display = isBB ? display.all : display.none, editable = isBB)
fill(bbUpperBand, bbLowerBand, color= isBB ? color.new(color.green, 90) : na, title="Bollinger Bands Background Fill", display = isBB ? display.all : display.none, editable = isBB)
lookbackRight = 5
lookbackLeft = 5
rangeUpper = 60
rangeLower = 5
bearColor = color.red
bullColor = color.green
textColor = color.white
noneColor = color.new(color.white, 100)
_calcBarsSince(cond) =>
ta.barssince(cond)
rsiLBR = rsi[lookbackRight]
// 1. Calculate Pivots Unconditionally
plFound = not na(ta.pivotlow(rsi, lookbackLeft, lookbackRight))
phFound = not na(ta.pivothigh(rsi, lookbackLeft, lookbackRight))
// 2. Calculate History Unconditionally
barsSincePL = _calcBarsSince(plFound[1])
barsSincePH = _calcBarsSince(phFound[1])
// 3. Check Ranges Unconditionally
inRangePL = rangeLower <= barsSincePL and barsSincePL <= rangeUpper
inRangePH = rangeLower <= barsSincePH and barsSincePH <= rangeUpper
// 4. Calculate Conditions
var bool bullCond = false
var bool bearCond = false
if calculateDivergence
rsiHL = rsiLBR > ta.valuewhen(plFound, rsiLBR, 1) and inRangePL
lowLBR = low[lookbackRight]
priceLL = lowLBR < ta.valuewhen(plFound, lowLBR, 1)
bullCond := priceLL and rsiHL and plFound
rsiLH = rsiLBR < ta.valuewhen(phFound, rsiLBR, 1) and inRangePH
highLBR = high[lookbackRight]
priceHH = highLBR > ta.valuewhen(phFound, highLBR, 1)
bearCond := priceHH and rsiLH and phFound
else
bullCond := false
bearCond := false
plot(plFound ? rsiLBR : na, offset = -lookbackRight, title = "Regular Bullish", linewidth = 2, color = (bullCond ? bullColor : noneColor), display = display.pane, editable = calculateDivergence)
plotshape(bullCond ? rsiLBR : na, offset = -lookbackRight, title = "Regular Bullish Label", text = " Bull ", style = shape.labelup, location = location.absolute, color = bullColor, textcolor = textColor, display = display.pane, editable = calculateDivergence)
plot(phFound ? rsiLBR : na, offset = -lookbackRight, title = "Regular Bearish", linewidth = 2, color = (bearCond ? bearColor : noneColor), display = display.pane, editable = calculateDivergence)
plotshape(bearCond ? rsiLBR : na, offset = -lookbackRight, title = "Regular Bearish Label", text = " Bear ", style = shape.labeldown, location = location.absolute, color = bearColor, textcolor = textColor, display = display.pane, editable = calculateDivergence)
alertcondition(bullCond, title='Regular Bullish Divergence', message="Found a new Regular Bullish Divergence.")
alertcondition(bearCond, title='Regular Bearish Divergence', message='Found a new Regular Bearish Divergence.')
// --- Panel Options (General) ---
g_panel = 'MTF Panel Options'
i_orientation = input.string('Vertical', 'Orientation', options = ['Vertical', 'Horizontal'], group = g_panel)
i_position = input.string('Bottom Right', 'Position', options = ['Top Left', 'Top Right', 'Top Center', 'Bottom Left', 'Bottom Right', 'Bottom Center', 'Middle Left', 'Middle Right', 'Middle Center'], group = g_panel)
i_border_width = input.int(1, 'Border Width', minval = 0, maxval = 10, group = g_panel, inline = 'border')
i_color_border = input.color(#000000, '', group = g_panel, inline = 'border')
i_showHeaders = input.bool(true, 'Show Headers', group = g_panel)
i_color_header_bg = input.color(#5d606b, 'Headers Background', group = g_panel, inline = 'header')
i_color_header_text = input.color(color.white, 'Text', group = g_panel, inline = 'header')
i_color_tf_bg = input.color(#2a2e39, 'Timeframe Background', group = g_panel, inline = 'tf')
i_color_tf_text = input.color(color.white, 'Text', group = g_panel, inline = 'tf')
i_debug = input.bool(false, 'Display colors palette (debug)', group = g_panel)
// --- RSI Colors (Conditional Formatting) ---
g_rsi = 'MTF RSI Colors'
i_threshold_ob = input.int(70, 'Overbought Threshold', minval=51, maxval=100, group = g_rsi)
i_color_ob = input.color(#128416, 'Overbought Background', inline = 'ob', group = g_rsi)
i_tcolor_ob = input.color(color.white, 'Text', inline = 'ob', group = g_rsi)
i_threshold_uptrend = input.int(60, 'Uptrend Threshold', minval=51, maxval=100, group = g_rsi)
i_color_uptrend = input.color(#2d472e, 'Uptrend Background', inline = 'up', group = g_rsi)
i_tcolor_uptrend = input.color(color.white, 'Text', inline = 'up', group = g_rsi)
i_color_mid = input.color(#131722, 'No Trend Background', group = g_rsi, inline = 'mid')
i_tcolor_mid = input.color(#b2b5be, 'Text', group = g_rsi, inline = 'mid')
i_threshold_downtrend = input.int(40, 'Downtrend Threshold', group = g_rsi, minval=0, maxval=49)
i_color_downtrend = input.color(#5b2e2e, 'Downtrend Background', group = g_rsi, inline = 'down')
i_tcolor_downtrend = input.color(color.white, 'Text', group = g_rsi, inline = 'down')
i_threshold_os = input.int(30, 'Oversold Threshold', minval=0, maxval=49, group = g_rsi)
i_color_os = input.color(#db3240, 'Oversold Background', group = g_rsi, inline = 'os')
i_tcolor_os = input.color(color.white, 'Text', group = g_rsi, inline = 'os')
// --- Individual RSI Settings (MTF Sources) ---
g_rsi1 = 'RSI #1'
i_rsi1_enabled = input.bool(true, title = 'Enabled', group = g_rsi1)
i_rsi1_tf = input.timeframe('5', 'Timeframe', group = g_rsi1)
i_rsi1_len = input.int(30, 'Length', minval = 1, group = g_rsi1)
i_rsi1_src = input.source(close, 'Source', group = g_rsi1) * 10000
v_rsi1 = i_rsi1_enabled ? request.security(syminfo.tickerid, i_rsi1_tf, ta.rsi(i_rsi1_src, i_rsi1_len)) : na
g_rsi2 = 'RSI #2'
i_rsi2_enabled = input.bool(true, title = 'Enabled', group = g_rsi2)
i_rsi2_tf = input.timeframe('15', 'Timeframe', group = g_rsi2)
i_rsi2_len = input.int(30, 'Length', minval = 1, group = g_rsi2)
i_rsi2_src = input.source(close, 'Source', group = g_rsi2) * 10000
v_rsi2 = i_rsi2_enabled ? request.security(syminfo.tickerid, i_rsi2_tf, ta.rsi(i_rsi2_src, i_rsi2_len)) : na
g_rsi3 = 'RSI #3'
i_rsi3_enabled = input.bool(true, title = 'Enabled', group = g_rsi3)
i_rsi3_tf = input.timeframe('60', 'Timeframe', group = g_rsi3)
i_rsi3_len = input.int(30, 'Length', minval = 1, group = g_rsi3)
i_rsi3_src = input.source(close, 'Source', group = g_rsi3) * 10000
v_rsi3 = i_rsi3_enabled ? request.security(syminfo.tickerid, i_rsi3_tf, ta.rsi(i_rsi3_src, i_rsi3_len)) : na
g_rsi4 = 'RSI #4'
i_rsi4_enabled = input.bool(true, title = 'Enabled', group = g_rsi4)
i_rsi4_tf = input.timeframe('240', 'Timeframe', group = g_rsi4)
i_rsi4_len = input.int(30, 'Length', minval = 1, group = g_rsi4)
i_rsi4_src = input.source(close, 'Source', group = g_rsi4) * 10000
v_rsi4 = i_rsi4_enabled ? request.security(syminfo.tickerid, i_rsi4_tf, ta.rsi(i_rsi4_src, i_rsi4_len)) : na
g_rsi5 = 'RSI #5'
i_rsi5_enabled = input.bool(true, title = 'Enabled', group = g_rsi5)
i_rsi5_tf = input.timeframe('D', 'Timeframe', group = g_rsi5)
i_rsi5_len = input.int(30, 'Length', minval = 1, group = g_rsi5)
i_rsi5_src = input.source(close, 'Source', group = g_rsi5) * 10000
v_rsi5 = i_rsi5_enabled ? request.security(syminfo.tickerid, i_rsi5_tf, ta.rsi(i_rsi5_src, i_rsi5_len)) : na
g_rsi6 = 'RSI #6'
i_rsi6_enabled = input.bool(true, title = 'Enabled', group = g_rsi6)
i_rsi6_tf = input.timeframe('W', 'Timeframe', group = g_rsi6)
i_rsi6_len = input.int(30, 'Length', minval = 1, group = g_rsi6)
i_rsi6_src = input.source(close, 'Source', group = g_rsi6) * 10000
v_rsi6 = i_rsi6_enabled ? request.security(syminfo.tickerid, i_rsi6_tf, ta.rsi(i_rsi6_src, i_rsi6_len)) : na
g_rsi7 = 'RSI #7'
i_rsi7_enabled = input.bool(false, title = 'Enabled', group = g_rsi7)
i_rsi7_tf = input.timeframe('W', 'Timeframe', group = g_rsi7)
i_rsi7_len = input.int(30, 'Length', minval = 1, group = g_rsi7)
i_rsi7_src = input.source(close, 'Source', group = g_rsi7) * 10000
v_rsi7 = i_rsi7_enabled ? request.security(syminfo.tickerid, i_rsi7_tf, ta.rsi(i_rsi7_src, i_rsi7_len)) : na
g_rsi8 = 'RSI #8'
i_rsi8_enabled = input.bool(false, title = 'Enabled', group = g_rsi8)
i_rsi8_tf = input.timeframe('W', 'Timeframe', group = g_rsi8)
i_rsi8_len = input.int(30, 'Length', minval = 1, group = g_rsi8)
i_rsi8_src = input.source(close, 'Source', group = g_rsi8) * 10000
v_rsi8 = i_rsi8_enabled ? request.security(syminfo.tickerid, i_rsi8_tf, ta.rsi(i_rsi8_src, i_rsi8_len)) : na
g_rsi9 = 'RSI #9'
i_rsi9_enabled = input.bool(false, title = 'Enabled', group = g_rsi9)
i_rsi9_tf = input.timeframe('W', 'Timeframe', group = g_rsi9)
i_rsi9_len = input.int(30, 'Length', minval = 1, group = g_rsi9)
i_rsi9_src = input.source(close, 'Source', group = g_rsi9) * 10000
v_rsi9 = i_rsi9_enabled ? request.security(syminfo.tickerid, i_rsi9_tf, ta.rsi(i_rsi9_src, i_rsi9_len)) : na
g_rsi10 = 'RSI #10'
i_rsi10_enabled = input.bool(false, title = 'Enabled', group = g_rsi10)
i_rsi10_tf = input.timeframe('W', 'Timeframe', group = g_rsi10)
i_rsi10_len = input.int(30, 'Length', minval = 1, group = g_rsi10)
i_rsi10_src = input.source(close, 'Source', group = g_rsi10) * 10000
v_rsi10 = i_rsi10_enabled ? request.security(syminfo.tickerid, i_rsi10_tf, ta.rsi(i_rsi10_src, i_rsi10_len)) : na
// --- Panel Helper Functions ---
// Function 4: String Position to Constant (Indentation cleaned)
f_StrPositionToConst(_p) =>
switch _p
'Top Left' => position.top_left
'Top Right' => position.top_right
'Top Center' => position.top_center
'Middle Left' => position.middle_left
'Middle Right' => position.middle_right
'Middle Center' => position.middle_center
'Bottom Left' => position.bottom_left
'Bottom Right' => position.bottom_right
'Bottom Center' => position.bottom_center
=> position.bottom_right
// Function 5: Timeframe to Human Readable (Indentation cleaned)
f_timeframeToHuman(_tf) =>
seconds = timeframe.in_seconds(_tf)
if seconds < 60
_tf
else if seconds < 3600
str.tostring(seconds / 60) + 'm'
else if seconds < 86400
str.tostring(seconds / 60 / 60) + 'h'
else
switch _tf
"1D" => "D"
"1W" => "W"
"1M" => "M"
=> str.tostring(_tf)
type TPanel
table src = na
bool vertical_orientation = true
int row = 0
int col = 0
// Method 1: Increment Column (Indentation cleaned)
method incCol(TPanel _panel) =>
if _panel.vertical_orientation
_panel.col += 1
else
_panel.row += 1
// Method 2: Increment Row (Indentation cleaned)
method incRow(TPanel _panel) =>
if not _panel.vertical_orientation
_panel.col += 1
_panel.row := 0
else
_panel.row += 1
_panel.col := 0
// Method 3: Add Cell (Indentation cleaned)
method add(TPanel _panel, string _v1, color _bg1, color _ctext1, string _v2, color _bg2, color _ctext2) =>
table.cell(_panel.src, _panel.col, _panel.row, _v1, text_color = _ctext1, bgcolor = _bg1)
_panel.incCol()
table.cell(_panel.src, _panel.col, _panel.row, _v2, text_color = _ctext2, bgcolor = _bg2)
_panel.incRow()
// Function 6: Background Color
f_bg(_rsi) =>
c_line = na(_rsi) ? i_color_mid :
_rsi >= i_threshold_ob ? i_color_ob :
_rsi >= i_threshold_uptrend ? i_color_uptrend :
_rsi <= i_threshold_os ? i_color_os :
_rsi <= i_threshold_downtrend ? i_color_downtrend :
i_color_mid
// Function 7: Text Color
f_rsi_text_color(_rsi) =>
c_line = na(_rsi) ? i_tcolor_mid :
_rsi >= i_threshold_ob ? i_tcolor_ob :
_rsi >= i_threshold_uptrend ? i_tcolor_uptrend :
_rsi <= i_threshold_os ? i_tcolor_os :
_rsi <= i_threshold_downtrend ? i_tcolor_downtrend :
i_tcolor_mid
f_formatRsi(_rsi) => na(_rsi) ? 'N/A' : str.tostring(_rsi, '0.00')
// --- Panel Execution Logic ---
if barstate.islast
v_panel = TPanel.new(vertical_orientation = i_orientation == 'Vertical')
v_max_rows = 20
v_panel.src := table.new(f_StrPositionToConst(i_position), v_max_rows, v_max_rows, border_width = i_border_width, border_color = i_color_border)
if i_showHeaders
v_panel.add('TF', i_color_header_bg, i_color_header_text, 'RSI', i_color_header_bg, i_color_header_text)
if i_rsi1_enabled
v_panel.add(f_timeframeToHuman(i_rsi1_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi1), f_bg(v_rsi1), f_rsi_text_color(v_rsi1))
if i_rsi2_enabled
v_panel.add(f_timeframeToHuman(i_rsi2_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi2), f_bg(v_rsi2), f_rsi_text_color(v_rsi2))
if i_rsi3_enabled
v_panel.add(f_timeframeToHuman(i_rsi3_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi3), f_bg(v_rsi3), f_rsi_text_color(v_rsi3))
if i_rsi4_enabled
v_panel.add(f_timeframeToHuman(i_rsi4_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi4), f_bg(v_rsi4), f_rsi_text_color(v_rsi4))
if i_rsi5_enabled
v_panel.add(f_timeframeToHuman(i_rsi5_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi5), f_bg(v_rsi5), f_rsi_text_color(v_rsi5))
if i_rsi6_enabled
v_panel.add(f_timeframeToHuman(i_rsi6_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi6), f_bg(v_rsi6), f_rsi_text_color(v_rsi6))
if i_rsi7_enabled
v_panel.add(f_timeframeToHuman(i_rsi7_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi7), f_bg(v_rsi7), f_rsi_text_color(v_rsi7))
if i_rsi8_enabled
v_panel.add(f_timeframeToHuman(i_rsi8_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi8), f_bg(v_rsi8), f_rsi_text_color(v_rsi8))
if i_rsi9_enabled
v_panel.add(f_timeframeToHuman(i_rsi9_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi9), f_bg(v_rsi9), f_rsi_text_color(v_rsi9))
if i_rsi10_enabled
v_panel.add(f_timeframeToHuman(i_rsi10_tf), i_color_tf_bg, i_color_tf_text, f_formatRsi(v_rsi10), f_bg(v_rsi10), f_rsi_text_color(v_rsi10))
if i_debug
t = table.new(position.middle_center, 21, 20, border_width = i_border_width, border_color = i_color_border)
v_panel2 = TPanel.new(t, vertical_orientation = i_orientation == 'Vertical')
v_panel2.add('Debug', i_color_header_bg, i_color_header_text, 'Colors', i_color_header_bg, i_color_header_text)
// Using a tuple array for debugging colors demo
// Final Syntax Correction: Use array.new<string>() and array.set() to avoid 'tuple()' function reference error
v_rows = 5 // We know we have 5 elements
demo = array.new<string>(v_rows, '') // Initialize array with 5 string elements, will hold string representation of the tuple
// We will push the elements as a *string* representation of the tuple, as Pine v6 allows
// and then parse them inside the loop if necessary.
// To preserve the structure (string, float) without the tuple() function:
// We must define two separate arrays if the 'tuple' function is truly unavailable.
tf_array = array.new<string>(v_rows)
rsi_array = array.new<float>(v_rows)
// Populate the arrays
array.set(tf_array, 0, 'Overbought')
array.set(rsi_array, 0, float(i_threshold_ob))
array.set(tf_array, 1, 'Uptrend')
array.set(rsi_array, 1, float(i_threshold_uptrend))
array.set(tf_array, 2, 'No Trend')
array.set(rsi_array, 2, 50.0)
array.set(tf_array, 3, 'Downtrend')
array.set(rsi_array, 3, float(i_threshold_downtrend))
array.set(tf_array, 4, 'Oversold')
array.set(rsi_array, 4, float(i_threshold_os))
// Iterate over the arrays using a simple index
for i = 0 to v_rows - 1
tf = array.get(tf_array, i)
rsi = array.get(rsi_array, i)
v_panel2.add(tf, i_color_tf_bg, i_color_tf_text, f_formatRsi(rsi), f_bg(rsi), f_rsi_text_color(rsi))
סקריפט מוגן
סקריפט זה פורסם כמקור סגור. עם זאת, תוכל להשתמש בו בחופשיות וללא כל מגבלות – למד עוד כאן
כתב ויתור
המידע והפרסומים אינם מיועדים להיות, ואינם מהווים, ייעוץ או המלצה פיננסית, השקעתית, מסחרית או מכל סוג אחר המסופקת או מאושרת על ידי TradingView. קרא עוד ב־תנאי השימוש.
סקריפט מוגן
סקריפט זה פורסם כמקור סגור. עם זאת, תוכל להשתמש בו בחופשיות וללא כל מגבלות – למד עוד כאן
כתב ויתור
המידע והפרסומים אינם מיועדים להיות, ואינם מהווים, ייעוץ או המלצה פיננסית, השקעתית, מסחרית או מכל סוג אחר המסופקת או מאושרת על ידי TradingView. קרא עוד ב־תנאי השימוש.