Indicator · Pine Script v6 · Own pane

Crowding Model BullVision

by regalouisei

This indicator monitors market-wide positioning across major cryptocurrency benchmarks and top altcoins.

View on GitHub

GitHub stars2on the repository
Pine versionv6current
Lines of code752
Settings40inputs
LicenceNone statedfile: MPL-2.0
Last update8 months ago25 Feb 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

752 lines of Pine Script v6 from pinescript/editors_picks/crowding-model-bullvision.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

crowding-model-bullvision.pine
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// BullVisionCapital

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%+=#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*==+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@*===+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#+#@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@#====+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@==#@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@#=====+%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*===#@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@#========*#%%%@@%%%%%%%%%%%@@@@@@@@@%#+====+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@#==============*+===========*%@#+========+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%*=============+=============#@*======+#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%#+========================#@%==+#%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%##+==================+%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+===============================@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%==================*@@@*=======@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%@@@%#*=============++*%#=====%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#==========================+=====*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*==================================+%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@*==========++=========================*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@#==========+@%+====================#+====#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@%+=========+@@@@#===================#@%+==%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@#=========+@@@@@@@@@%%%%%%%*==============@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@#========+@@@@@@@@@@@@@@@@@@@@@#========+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@%+=======%@@@@@@@@@@@@+@@@@@@@@@@@%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@%+=====*@@@@@@@%@@@%+==#@@@@@@#%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+====#@@@@@@@=@@@%+==#@@@@@===#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#===#@@@@@%*=*%@%+==#@@@@@==*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%*=#@@@@@#+==%@%+==#@@@@+=#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%@@@@@@#+==%@%+==#@@@+=%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#+==%@@@=@@@@**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#+==%@@@#@@@#%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%=%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


//@version=6
indicator(" Crowding model ║ BullVision",shorttitle = "👥 Crowding Model ║ BullVision👥", overlay=false)

// ==================== INPUTS ====================
group1 = '🎨 Visual Settings'
int BarScale = input.int(150, 'Bar Scale', group = group1)
bool showMainAssets = input.bool(true, 'Show TOTAL, BTC, ETH, OTHERS', group = group1)
bool showGradientBg = input.bool(true, 'Show Gradient Background', group = group1)

bool showCrowdingPanel = input.bool(true, 'Show Crowding Analytics Panel', group = group1)

group2 = '📊 Indicator Parameters'
int rsi_length = input.int(14, 'RSI Length', minval = 5, maxval = 50, group = group2)
int Z_score_L = input.int(90, 'Z-score lookback', minval = 20, maxval = 200, group = group2)
float crowdingThreshold = input.float(40.0, 'Crowding Alert Threshold %', minval = 20, maxval = 60, group = group2)

group3 = '🎯 Zone Settings'
bool showQuadrantLabels = input.bool(true, 'Show Quadrant Labels', group = group3)
bool showDangerZones = input.bool(true, 'Highlight Danger Zones', group = group3)
float dangerRSIHigh = input.float(70.0, 'Danger RSI High', minval = 60, maxval = 90, group = group3)
float dangerRSILow = input.float(30.0, 'Danger RSI Low', minval = 10, maxval = 40, group = group3)

// ==================== ASSET TICKERS ====================
groupAssets = '📈 Asset Tickers'
symbolINDEX = input.symbol('CRYPTOCAP:TOTAL', 'MARKET INDEX', group = groupAssets)
symbolINDEX2 = input.symbol('CRYPTOCAP:OTHERS', 'SECONDARY INDEX', group = groupAssets)
symbolMAIN = input.symbol('INDEX:BTCUSD', 'MAIN ASSET ', group = groupAssets)
symbolMAIN2 = input.symbol('INDEX:ETHUSD', 'SECOND MAIN ASSET', group = groupAssets)

// Editable symbols for all 36 coins
symbol1 = input.symbol('CRYPTO:BNBUSD', 'Asset 1', group = groupAssets)
symbol2 = input.symbol('CRYPTO:SOLUSD', 'Asset 2 ', group = groupAssets)
symbol3 = input.symbol('CRYPTO:XRPUSD', 'Asset 3 ', group = groupAssets)
symbol4 = input.symbol('CRYPTO:ADAUSD', 'Asset 4 ', group = groupAssets)
symbol5 = input.symbol('CRYPTO:DOGEUSD', 'Asset 5 ', group = groupAssets)
symbol6 = input.symbol('CRYPTO:AVAXUSD', 'Asset 6 ', group = groupAssets)
symbol7 = input.symbol('CRYPTO:SHIBUSD', 'Asset 7 ', group = groupAssets)
symbol8 = input.symbol('CRYPTO:TRXUSD', 'Asset 8 ', group = groupAssets)
symbol9 = input.symbol('CRYPTO:DOTUSD', 'Asset 9 ', group = groupAssets)
symbol10 = input.symbol('CRYPTO:LINKUSD', 'Asset 10 ', group = groupAssets)
symbol11 = input.symbol('CRYPTO:MATICUSD', 'Asset 11 ', group = groupAssets)
symbol12 = input.symbol('CRYPTO:UNIUSD', 'Asset 12 ', group = groupAssets)
symbol13 = input.symbol('CRYPTO:TONUSD', 'Asset 13 ', group = groupAssets)
symbol14 = input.symbol('CRYPTO:BCHUSD', 'Asset 14 ', group = groupAssets)
symbol15 = input.symbol('CRYPTO:LTCUSD', 'Asset 15 ', group = groupAssets)
symbol16 = input.symbol('CRYPTO:ICPUSD', 'Asset 16 ', group = groupAssets)
symbol17 = input.symbol('CRYPTO:FILUSD', 'Asset 17 ', group = groupAssets)
symbol18 = input.symbol('CRYPTO:ETCUSD', 'Asset 18 ', group = groupAssets)
symbol19 = input.symbol('CRYPTO:ATOMUSD', 'Asset 19 ', group = groupAssets)
symbol20 = input.symbol('CRYPTO:IMXUSD', 'Asset 20 ', group = groupAssets)
symbol21 = input.symbol('CRYPTO:NEARUSD', 'Asset 21 ', group = groupAssets)
symbol22 = input.symbol('CRYPTO:LEOUSD', 'Asset 22 ', group = groupAssets)
symbol23 = input.symbol('COINBASE:STXUSD', 'Asset 23 ', group = groupAssets)
symbol24 = input.symbol('COINBASE:APTUSD', 'Asset 24 ', group = groupAssets)
symbol25 = input.symbol('KUCOIN:TAOUSDT', 'Asset 25 ', group = groupAssets)
symbol26 = input.symbol('CRYPTO:OPUSD', 'Asset 26 ', group = groupAssets)
symbol27 = input.symbol('CRYPTO:XLMUSD', 'Asset 27 ', group = groupAssets)
symbol28 = input.symbol('CRYPTO:KASUSD', 'Asset 28 ', group = groupAssets)
symbol29 = input.symbol('CRYPTO:HBARUSD', 'Asset 29 ', group = groupAssets)
symbol30 = input.symbol('CRYPTO:CROUSD', 'Asset 30 ', group = groupAssets)
symbol31 = input.symbol('CRYPTO:INJUSD', 'Asset 31 ', group = groupAssets)
symbol32 = input.symbol('CRYPTO:VETUSD', 'Asset 32 ', group = groupAssets)
symbol33 = input.symbol('CRYPTO:OKBUSD', 'Asset 33 ', group = groupAssets)
symbol34 = input.symbol('CRYPTO:GRTUSD', 'Asset 34 ', group = groupAssets)
symbol35 = input.symbol('CRYPTO:LDOUSD', 'Asset 35 ', group = groupAssets)
symbol36 = input.symbol('CRYPTO:RNDRUSD', 'Asset 36 ', group = groupAssets)

// ==================== ASSET DEFINITIONS ====================
total = request.security(symbolINDEX, 'D', close)
others = request.security(symbolINDEX2, 'D', close)
btc = request.security(symbolMAIN, 'D', close)
eth = request.security(symbolMAIN2, 'D', close)

asset1 = request.security(symbol1, 'D', close)
asset2 = request.security(symbol2, 'D', close)
asset3 = request.security(symbol3, 'D', close)
asset4 = request.security(symbol4, 'D', close)
asset5 = request.security(symbol5, 'D', close)
asset6 = request.security(symbol6, 'D', close)
asset7 = request.security(symbol7, 'D', close)
asset8 = request.security(symbol8, 'D', close)
asset9 = request.security(symbol9, 'D', close)
asset10 = request.security(symbol10, 'D', close)
asset11 = request.security(symbol11, 'D', close)
asset12 = request.security(symbol12, 'D', close)
asset13 = request.security(symbol13, 'D', close)
asset14 = request.security(symbol14, 'D', close)
asset15 = request.security(symbol15, 'D', close)
asset16 = request.security(symbol16, 'D', close)
asset17 = request.security(symbol17, 'D', close)
asset18 = request.security(symbol18, 'D', close)
asset19 = request.security(symbol19, 'D', close)
asset20 = request.security(symbol20, 'D', close)
asset21 = request.security(symbol21, 'D', close)
asset22 = request.security(symbol22, 'D', close)
asset23 = request.security(symbol23, 'D', close)
asset24 = request.security(symbol24, 'D', close)
asset25 = request.security(symbol25, 'D', close)
asset26 = request.security(symbol26, 'D', close)
asset27 = request.security(symbol27, 'D', close)
asset28 = request.security(symbol28, 'D', close)
asset29 = request.security(symbol29, 'D', close)
asset30 = request.security(symbol30, 'D', close)
asset31 = request.security(symbol31, 'D', close)
asset32 = request.security(symbol32, 'D', close)
asset33 = request.security(symbol33, 'D', close)
asset34 = request.security(symbol34, 'D', close)
asset35 = request.security(symbol35, 'D', close)
asset36 = request.security(symbol36, 'D', close)

// ==================== REST OF SCRIPT ====================

mainDisplayNames = array.from(str.replace_all(str.substring(symbolINDEX, str.pos(symbolINDEX, ":") + 1), "USD", ""), str.replace_all(str.substring(symbolINDEX2, str.pos(symbolINDEX2, ":") + 1), "USD", ""), str.replace_all(str.substring(symbolMAIN, str.pos(symbolMAIN, ":") + 1), "USD", ""), str.replace_all(str.substring(symbolMAIN2, str.pos(symbolMAIN2, ":") + 1), "USD", ""))
displayNames = array.from(str.replace_all(str.substring(symbol1, str.pos(symbol1, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol2, str.pos(symbol2, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol3, str.pos(symbol3, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol4, str.pos(symbol4, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol5, str.pos(symbol5, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol6, str.pos(symbol6, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol7, str.pos(symbol7, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol8, str.pos(symbol8, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol9, str.pos(symbol9, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol10, str.pos(symbol10, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol11, str.pos(symbol11, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol12, str.pos(symbol12, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol13, str.pos(symbol13, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol14, str.pos(symbol14, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol15, str.pos(symbol15, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol16, str.pos(symbol16, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol17, str.pos(symbol17, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol18, str.pos(symbol18, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol19, str.pos(symbol19, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol20, str.pos(symbol20, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol21, str.pos(symbol21, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol22, str.pos(symbol22, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol23, str.pos(symbol23, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol24, str.pos(symbol24, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol25, str.pos(symbol25, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol26, str.pos(symbol26, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol27, str.pos(symbol27, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol28, str.pos(symbol28, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol29, str.pos(symbol29, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol30, str.pos(symbol30, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol31, str.pos(symbol31, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol32, str.pos(symbol32, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol33, str.pos(symbol33, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol34, str.pos(symbol34, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol35, str.pos(symbol35, ":") + 1), "USD", ""), str.replace_all(str.substring(symbol36, str.pos(symbol36, ":") + 1), "USD", ""))

// ==================== CALCULATION FUNCTIONS ====================

calcZScore(source, lookback) =>
    mean = ta.sma(source, lookback)
    stdDev = ta.stdev(source, lookback)
    zScore = stdDev > 0 ? (source - mean) / stdDev : 0
    math.max(-3, math.min(3, zScore))

// ==================== RSI CALCULATIONS ====================
// Main assets
rsiINDEX = ta.rsi(total, rsi_length)
rsiINDEX2 = ta.rsi(others, rsi_length)
rsiMAIN1 = ta.rsi(btc, rsi_length)
rsiMAIN2 = ta.rsi(eth, rsi_length)

// All crypto RSIs
rsi_1 = ta.rsi(asset1, rsi_length)
rsi_2 = ta.rsi(asset2, rsi_length)
rsi_3 = ta.rsi(asset3, rsi_length)
rsi_4 = ta.rsi(asset4, rsi_length)
rsi_5 = ta.rsi(asset5, rsi_length)
rsi_6 = ta.rsi(asset6, rsi_length)
rsi_7 = ta.rsi(asset7, rsi_length)
rsi_8 = ta.rsi(asset8, rsi_length)
rsi_9 = ta.rsi(asset9, rsi_length)
rsi_10 = ta.rsi(asset10, rsi_length)
rsi_11 = ta.rsi(asset11, rsi_length)
rsi_12 = ta.rsi(asset12, rsi_length)
rsi_13 = ta.rsi(asset13, rsi_length)
rsi_14 = ta.rsi(asset14, rsi_length)
rsi_15 = ta.rsi(asset15, rsi_length)
rsi_16 = ta.rsi(asset16, rsi_length)
rsi_17 = ta.rsi(asset17, rsi_length)
rsi_18 = ta.rsi(asset18, rsi_length)
rsi_19 = ta.rsi(asset19, rsi_length)
rsi_20 = ta.rsi(asset20, rsi_length)
rsi_21 = ta.rsi(asset21, rsi_length)
rsi_22 = ta.rsi(asset22, rsi_length)
rsi_23 = ta.rsi(asset23, rsi_length)
rsi_24 = ta.rsi(asset24, rsi_length)
rsi_25 = ta.rsi(asset25, rsi_length)
rsi_26 = ta.rsi(asset26, rsi_length)
rsi_27 = ta.rsi(asset27, rsi_length)
rsi_28 = ta.rsi(asset28, rsi_length)
rsi_29 = ta.rsi(asset29, rsi_length)
rsi_30 = ta.rsi(asset30, rsi_length)
rsi_31 = ta.rsi(asset31, rsi_length)
rsi_32 = ta.rsi(asset32, rsi_length)
rsi_33 = ta.rsi(asset33, rsi_length)
rsi_34 = ta.rsi(asset34, rsi_length)
rsi_35 = ta.rsi(asset35, rsi_length)
rsi_36 = ta.rsi(asset36, rsi_length)

// ==================== Z-SCORE CALCULATIONS ====================
// Main assets
zScoreINDEX  = calcZScore(total, Z_score_L)
zScoreINDEX2 = calcZScore(others, Z_score_L)
zScoreMAIN1 = calcZScore(btc, Z_score_L)
zScoreMAIN2 = calcZScore(eth, Z_score_L)

// All crypto Z-scores
zScore_1 = calcZScore(asset1, Z_score_L)
zScore_2 = calcZScore(asset2, Z_score_L)
zScore_3 = calcZScore(asset3, Z_score_L)
zScore_4 = calcZScore(asset4, Z_score_L)
zScore_5 = calcZScore(asset5, Z_score_L)
zScore_6 = calcZScore(asset6, Z_score_L)
zScore_7 = calcZScore(asset7, Z_score_L)
zScore_8 = calcZScore(asset8, Z_score_L)
zScore_9 = calcZScore(asset9, Z_score_L)
zScore_10 = calcZScore(asset10, Z_score_L)
zScore_11 = calcZScore(asset11, Z_score_L)
zScore_12 = calcZScore(asset12, Z_score_L)
zScore_13 = calcZScore(asset13, Z_score_L)
zScore_14 = calcZScore(asset14, Z_score_L)
zScore_15 = calcZScore(asset15, Z_score_L)
zScore_16 = calcZScore(asset16, Z_score_L)
zScore_17 = calcZScore(asset17, Z_score_L)
zScore_18 = calcZScore(asset18, Z_score_L)
zScore_19 = calcZScore(asset19, Z_score_L)
zScore_20 = calcZScore(asset20, Z_score_L)
zScore_21 = calcZScore(asset21, Z_score_L)
zScore_22 = calcZScore(asset22, Z_score_L)
zScore_23 = calcZScore(asset23, Z_score_L)
zScore_24 = calcZScore(asset24, Z_score_L)
zScore_25 = calcZScore(asset25, Z_score_L)
zScore_26 = calcZScore(asset26, Z_score_L)
zScore_27 = calcZScore(asset27, Z_score_L)
zScore_28 = calcZScore(asset28, Z_score_L)
zScore_29 = calcZScore(asset29, Z_score_L)
zScore_30 = calcZScore(asset30, Z_score_L)
zScore_31 = calcZScore(asset31, Z_score_L)
zScore_32 = calcZScore(asset32, Z_score_L)
zScore_33 = calcZScore(asset33, Z_score_L)
zScore_34 = calcZScore(asset34, Z_score_L)
zScore_35 = calcZScore(asset35, Z_score_L)
zScore_36 = calcZScore(asset36, Z_score_L)

// ==================== ENHANCED SCATTER FUNCTION ====================
scatter(float rsiValue, float zScore, color clr, string symbol, int scale, string category = 'other') =>
    if barstate.islast
        int xPosition = bar_index - math.round(100 - rsiValue)
        float yPosition = zScore


        labelStyle = category == 'INDEX' ? label.style_circle : category == 'MAIN' ? label.style_diamond : label.style_label_center

        labelSize = category == 'INDEX' ? size.large : category == 'MAIN' ? size.normal : size.small



        var label rsiLabel = label.new(x = xPosition, y = yPosition, text = symbol, color = clr, style = labelStyle, size = labelSize)

        
        emoji = rsiValue > 80 ? '🔥' : rsiValue < 20 ? '❄️' : ''
        labelText = emoji + symbol + '\n' + 'RSI: ' + str.tostring(math.round(rsiValue, 1)) + '\nZ: ' + str.tostring(math.round(zScore, 1))

        label.set_text(rsiLabel, labelText)
        label.set_x(rsiLabel, xPosition)
        label.set_y(rsiLabel, yPosition)
        label.set_color(rsiLabel, clr)
        label.set_textcolor(rsiLabel, color.white)

// ==================== BACKGROUND VISUALIZATION ====================
float zScoreMin = -3
float zScoreMax = 3
int xFirstBar = bar_index[1] - 100
int xLastBar = bar_index[1]
int xMidBar = bar_index[1] - 50

var box gradientBox1 = na
var box gradientBox2 = na
var box gradientBox3 = na
var box gradientBox4 = na
var box bgBox = na

if showGradientBg

    box.delete(gradientBox1[1])
    box.delete(gradientBox2[1])
    box.delete(gradientBox3[1])
    box.delete(gradientBox4[1])
    box.delete(bgBox[1])

    // Redraw gradient boxes
    gradientBox1 := box.new(left = xFirstBar, top = zScoreMax, right = xLastBar, bottom = zScoreMax * 0.5, bgcolor = color.new(#1a1f2e, 80), border_color = na)
    gradientBox2 := box.new(left = xFirstBar, top = zScoreMax * 0.5, right = xLastBar, bottom = 0, bgcolor = color.new(#151923, 80), border_color = na)
    gradientBox3 := box.new(left = xFirstBar, top = 0, right = xLastBar, bottom = zScoreMin * 0.5, bgcolor = color.new(#11141c, 80), border_color = na)
    gradientBox4 := box.new(left = xFirstBar, top = zScoreMin * 0.5, right = xLastBar, bottom = zScoreMin, bgcolor = color.new(#0d0f15, 80), border_color = na)
    gradientBox4
else 
    box.delete(gradientBox1[1])
    box.delete(gradientBox2[1])
    box.delete(gradientBox3[1])
    box.delete(gradientBox4[1])
    box.delete(bgBox[1])

    bgBox := box.new(left = xFirstBar, top = zScoreMax, right = xLastBar, bottom = zScoreMin, bgcolor = color.new(#0a0a0a, 95), border_color = color.new(#2a2a2a, 80))
    bgBox
    // Professional grid lines
var line hMidline = line.new(x1 = xFirstBar, y1 = 0, x2 = xLastBar, y2 = 0, width = 1, color = color.new(#404040, 50), style = line.style_solid)
var line vMidline = line.new(x1 = xMidBar, y1 = zScoreMin, x2 = xMidBar, y2 = zScoreMax, width = 1, color = color.new(#404040, 50), style = line.style_solid)

// Subtle additional grid lines
var line hLine1 = line.new(x1 = xFirstBar, y1 = 1.5, x2 = xLastBar, y2 = 1.5, width = 1, color = color.new(#303030, 80), style = line.style_dotted)
var line hLine2 = line.new(x1 = xFirstBar, y1 = -1.5, x2 = xLastBar, y2 = -1.5, width = 1, color = color.new(#303030, 80), style = line.style_dotted)
var line vLine1 = line.new(x1 = bar_index[1] - 25, y1 = zScoreMin, x2 = bar_index[1] - 25, y2 = zScoreMax, width = 1, color = color.new(#303030, 80), style = line.style_dotted)
var line vLine2 = line.new(x1 = bar_index[1] - 75, y1 = zScoreMin, x2 = bar_index[1] - 75, y2 = zScoreMax, width = 1, color = color.new(#303030, 80), style = line.style_dotted)

// Update all lines
line.set_x1(hMidline, xFirstBar)
line.set_x2(hMidline, xLastBar)
line.set_x1(vMidline, xMidBar)
line.set_x2(vMidline, xMidBar)
line.set_x1(hLine1, xFirstBar)
line.set_x2(hLine1, xLastBar)
line.set_x1(hLine2, xFirstBar)
line.set_x2(hLine2, xLastBar)
line.set_x1(vLine1, bar_index[1] - 25)
line.set_x2(vLine1, bar_index[1] - 25)
line.set_x1(vLine2, bar_index[1] - 75)
line.set_x2(vLine2, bar_index[1] - 75)

// ==================== DANGER ZONES ====================
if showDangerZones

    var box dangerZone1 = box.new(left = bar_index[1] - math.round(100 - dangerRSIHigh), top = zScoreMax, right = xLastBar, bottom = 1, bgcolor = color.new(#cc2936, 94), border_color = color.new(#cc2936, 85))


    var box dangerZone2 = box.new(left = xFirstBar, top = -1, right = bar_index[1] - math.round(100 - dangerRSILow), bottom = zScoreMin, bgcolor = color.new(#26a653, 94), border_color = color.new(#26a653, 85))


    box.set_left(dangerZone1, bar_index[1] - math.round(100 - dangerRSIHigh))
    box.set_right(dangerZone1, xLastBar)
    box.set_right(dangerZone2, bar_index[1] - math.round(100 - dangerRSILow))
    box.set_left(dangerZone2, xFirstBar)

// ==================== QUADRANT LABELS ====================

var label overboughtLabel = na
var label recoveryLabel = na
var label oversoldLabel = na
var label consolidationLabel = na

// Quadrant labels
if showQuadrantLabels and barstate.islast
    // Delete previous quadrant labels to avoid overlap
    label.delete(overboughtLabel[1])
    label.delete(recoveryLabel[1])
    label.delete(oversoldLabel[1])
    label.delete(consolidationLabel[1])

  
    overboughtLabel := label.new(x = bar_index[1] - 5, y = 2.7, text = 'Overbought\nExtended', style = label.style_label_center, color = color.new(#cc2936, 85), textcolor = color.new(color.white, 20), size = size.normal)
    recoveryLabel := label.new(x = bar_index[1] - 94, y = 2.7, text = 'Recovery\nPhase', style = label.style_label_center, color = color.new(#ff9800, 85), textcolor = color.new(color.white, 20), size = size.normal)
    oversoldLabel := label.new(x = bar_index[1] - 94, y = -2.7, text = 'Oversold\nCompressed', style = label.style_label_center, color = color.new(#2196f3, 85), textcolor = color.new(color.white, 20), size = size.normal)
    consolidationLabel := label.new(x = bar_index[1] - 5, y = -2.7, text = 'Strong\nConsolidation', style = label.style_label_center, color = color.new(#26a653, 85), textcolor = color.new(color.white, 20), size = size.normal)
    consolidationLabel

// ==================== SCATTER PLOT ====================
if barstate.islast
    if showMainAssets

        scatter(rsiINDEX[1], zScoreINDEX[1], color.new(#7c3aed, 5),array.get(mainDisplayNames,0), BarScale, 'INDEX')
        scatter(rsiINDEX2[1], zScoreINDEX2[1], color.new(#ea580c, 5),array.get(mainDisplayNames,1), BarScale, 'INDEX')
        scatter(rsiMAIN1[1], zScoreMAIN1[1], color.new(#f59e0b, 20),array.get(mainDisplayNames,2), BarScale, 'MAIN')
        scatter(rsiMAIN2[1], zScoreMAIN2[1], color.new(#3b82f6, 20),array.get(mainDisplayNames,3), BarScale, 'MAIN')

    scatter(rsi_1[1], zScore_1[1], color.new(#6366f1, 30), array.get(displayNames, 0), BarScale)
    scatter(rsi_2[1], zScore_2[1], color.new(#8b5cf6, 30), array.get(displayNames, 1), BarScale)
    scatter(rsi_3[1], zScore_3[1], color.new(#06b6d4, 30), array.get(displayNames, 2), BarScale)
    scatter(rsi_4[1], zScore_4[1], color.new(#0891b2, 30), array.get(displayNames, 3), BarScale)
    scatter(rsi_5[1], zScore_5[1], color.new(#d97706, 30), array.get(displayNames, 4), BarScale)
    scatter(rsi_6[1], zScore_6[1], color.new(#dc2626, 30), array.get(displayNames, 5), BarScale)
    scatter(rsi_7[1], zScore_7[1], color.new(#c2410c, 30), array.get(displayNames, 6), BarScale)
    scatter(rsi_8[1], zScore_8[1], color.new(#be123c, 30), array.get(displayNames, 7), BarScale)
    scatter(rsi_9[1], zScore_9[1], color.new(#be185d, 30), array.get(displayNames, 8), BarScale)
    scatter(rsi_10[1], zScore_10[1], color.new(#4f46e5, 30), array.get(displayNames, 9), BarScale)
    scatter(rsi_11[1], zScore_11[1], color.new(#7c3aed, 30), array.get(displayNames, 10), BarScale)
    scatter(rsi_12[1], zScore_12[1], color.new(#e11d48, 30), array.get(displayNames, 11), BarScale)
    scatter(rsi_13[1], zScore_13[1], color.new(#0ea5e9, 30), array.get(displayNames, 12), BarScale)
    scatter(rsi_14[1], zScore_14[1], color.new(#16a34a, 30), array.get(displayNames, 13), BarScale)

    scatter(rsi_15[1], zScore_15[1], color.new(#64748b, 40), array.get(displayNames, 14), BarScale)
    scatter(rsi_16[1], zScore_16[1], color.new(#475569, 40), array.get(displayNames, 15), BarScale)
    scatter(rsi_17[1], zScore_17[1], color.new(#334155, 40), array.get(displayNames, 16), BarScale)
    scatter(rsi_18[1], zScore_18[1], color.new(#1e293b, 40), array.get(displayNames, 17), BarScale)
    scatter(rsi_19[1], zScore_19[1], color.new(#0f172a, 40), array.get(displayNames, 18), BarScale)
    scatter(rsi_20[1], zScore_20[1], color.new(#581c87, 40), array.get(displayNames, 19), BarScale)
    scatter(rsi_21[1], zScore_21[1], color.new(#6b21a8, 40), array.get(displayNames, 20), BarScale)
    scatter(rsi_22[1], zScore_22[1], color.new(#86198f, 40), array.get(displayNames, 21), BarScale)
    scatter(rsi_23[1], zScore_23[1], color.new(#a21caf, 40), array.get(displayNames, 22), BarScale)
    scatter(rsi_24[1], zScore_24[1], color.new(#134e4a, 40), array.get(displayNames, 23), BarScale)
    scatter(rsi_25[1], zScore_25[1], color.new(#115e59, 40), array.get(displayNames, 24), BarScale)
    scatter(rsi_26[1], zScore_26[1], color.new(#0f766e, 40), array.get(displayNames, 25), BarScale)
    scatter(rsi_27[1], zScore_27[1], color.new(#0d9488, 40), array.get(displayNames, 26), BarScale)
    scatter(rsi_28[1], zScore_28[1], color.new(#14b8a6, 40), array.get(displayNames, 27), BarScale)
    scatter(rsi_29[1], zScore_29[1], color.new(#1e3a8a, 40), array.get(displayNames, 28), BarScale)
    scatter(rsi_30[1], zScore_30[1], color.new(#1e40af, 40), array.get(displayNames, 29), BarScale)
    scatter(rsi_31[1], zScore_31[1], color.new(#2563eb, 40), array.get(displayNames, 30), BarScale)
    scatter(rsi_32[1], zScore_32[1], color.new(#0284c7, 40), array.get(displayNames, 31), BarScale)
    scatter(rsi_33[1], zScore_33[1], color.new(#0369a1, 40), array.get(displayNames, 32), BarScale)
    scatter(rsi_34[1], zScore_34[1], color.new(#075985, 40), array.get(displayNames, 33), BarScale)
    scatter(rsi_35[1], zScore_35[1], color.new(#0c4a6e, 40), array.get(displayNames, 34), BarScale)
    scatter(rsi_36[1], zScore_36[1], color.new(#164e63, 40), array.get(displayNames, 35), BarScale)
    scatter(rsi_30[1], zScore_30[1], color.new(#003b84, 20), array.get(displayNames, 29), BarScale)
    scatter(rsi_31[1], zScore_31[1], color.new(#00f0ff, 20), array.get(displayNames, 30), BarScale)
    scatter(rsi_32[1], zScore_32[1], color.new(#3ac1d0, 20), array.get(displayNames, 31), BarScale)
    scatter(rsi_33[1], zScore_33[1], color.new(#000000, 20), array.get(displayNames, 32), BarScale)
    scatter(rsi_34[1], zScore_34[1], color.new(#6f4cff, 20), array.get(displayNames, 33), BarScale)
    scatter(rsi_35[1], zScore_35[1], color.new(#22a1f0, 20), array.get(displayNames, 34), BarScale)
    scatter(rsi_36[1], zScore_36[1], color.new(#000000, 20), array.get(displayNames, 35), BarScale)

// ==================== CROWDING ANALYTICS PANEL ====================

totalAssets = (showMainAssets ? 4 : 0) + 36
fomoCount = 0
fearCount = 0
recoveryCount = 0
strengthCount = 0


if showCrowdingPanel
    var table panel = table.new(position.top_right, 3, 8, bgcolor = color.new(#0d1117, 80), border_width = 1, border_color = color.new(#30363d, 50))

    if barstate.islast
        // Title
        table.cell(panel, 0, 0, '🎯 CROWDING ANALYTICS', text_color = #58a6ff, text_size = size.normal, bgcolor = color.new(#161b22, 50))
        table.merge_cells(panel, 0, 0, 2, 0)



        // Count main assets
        if showMainAssets
            // BTC
            if rsiMAIN1 > 50 and zScoreMAIN1 > 0
                fomoCount := fomoCount + 1
                fomoCount
            else if rsiMAIN1 <= 50 and zScoreMAIN1 > 0
                recoveryCount := recoveryCount + 1
                recoveryCount
            else if rsiMAIN1 <= 50 and zScoreMAIN1 <= 0
                fearCount := fearCount + 1
                fearCount
            else
                strengthCount := strengthCount + 1
                strengthCount

            // ETH
            if rsiMAIN2 > 50 and zScoreMAIN2 > 0
                fomoCount := fomoCount + 1
                fomoCount
            else if rsiMAIN2 <= 50 and zScoreMAIN2 > 0
                recoveryCount := recoveryCount + 1
                recoveryCount
            else if rsiMAIN2 <= 50 and zScoreMAIN2 <= 0
                fearCount := fearCount + 1
                fearCount
            else
                strengthCount := strengthCount + 1
                strengthCount

            // TOTAL
            if rsiINDEX > 50 and zScoreINDEX > 0
                fomoCount := fomoCount + 1
                fomoCount
            else if rsiINDEX <= 50 and zScoreINDEX > 0
                recoveryCount := recoveryCount + 1
                recoveryCount
            else if rsiINDEX <= 50 and zScoreINDEX <= 0
                fearCount := fearCount + 1
                fearCount
            else
                strengthCount := strengthCount + 1
                strengthCount

            // OTHERS
            if rsiINDEX2 > 50 and zScoreINDEX2 > 0
                fomoCount := fomoCount + 1
                fomoCount
            else if rsiINDEX2 <= 50 and zScoreINDEX2 > 0
                recoveryCount := recoveryCount + 1
                recoveryCount
            else if rsiINDEX2 <= 50 and zScoreINDEX2 <= 0
                fearCount := fearCount + 1
                fearCount
            else
                strengthCount := strengthCount + 1
                strengthCount

        if rsi_1 > 50 and zScore_1 > 0
            fomoCount := fomoCount + 1
            fomoCount
        else if rsi_1 <= 50 and zScore_1 > 0
            recoveryCount := recoveryCount + 1
            recoveryCount
        else if rsi_1 <= 50 and zScore_1 <= 0
            fearCount := fearCount + 1
            fearCount
        else
            strengthCount := strengthCount + 1
            strengthCount

        if rsi_2 > 50 and zScore_2 > 0
            fomoCount := fomoCount + 1
            fomoCount
        else if rsi_2 <= 50 and zScore_2 > 0
            recoveryCount := recoveryCount + 1
            recoveryCount
        else if rsi_2 <= 50 and zScore_2 <= 0
            fearCount := fearCount + 1
            fearCount
        else
            strengthCount := strengthCount + 1
            strengthCount

        if rsi_3 > 50 and zScore_3 > 0
            fomoCount := fomoCount + 1
            fomoCount
        else if rsi_3 <= 50 and zScore_3 > 0
            recoveryCount := recoveryCount + 1
            recoveryCount
        else if rsi_3 <= 50 and zScore_3 <= 0
            fearCount := fearCount + 1
            fearCount
        else
            strengthCount := strengthCount + 1
            strengthCount

        if rsi_4 > 50 and zScore_4 > 0
            fomoCount := fomoCount + 1
            fomoCount
        else if rsi_4 <= 50 and zScore_4 > 0
            recoveryCount := recoveryCount + 1
            recoveryCount
        else if rsi_4 <= 50 and zScore_4 <= 0
            fearCount := fearCount + 1
            fearCount
        else
            strengthCount := strengthCount + 1
            strengthCount

        if rsi_5 > 50 and zScore_5 > 0
            fomoCount := fomoCount + 1
            fomoCount
        else if rsi_5 <= 50 and zScore_5 > 0
            recoveryCount := recoveryCount + 1
            recoveryCount
        else if rsi_5 <= 50 and zScore_5 <= 0
            fearCount := fearCount + 1
            fearCount
        else
            strengthCount := strengthCount + 1
            strengthCount

        if rsi_6 > 50 and zScore_6 > 0
            fomoCount := fomoCount + 1
            fomoCount
        else if rsi_6 <= 50 and zScore_6 > 0
            recoveryCount := recoveryCount + 1
            recoveryCount
        else if rsi_6 <= 50 and zScore_6 <= 0
            fearCount := fearCount + 1
            fearCount
        else
            strengthCount := strengthCount + 1
            strengthCount

        if rsi_7 > 50 and zScore_7 > 0
            fomoCount := fomoCount + 1
            fomoCount
        else if rsi_7 <= 50 and zScore_7 > 0
            recoveryCount := recoveryCount + 1
            recoveryCount
        else if rsi_7 <= 50 and zScore_7 <= 0
            fearCount := fearCount + 1
            fearCount
        else
            strengthCount := strengthCount + 1
            strengthCount

        if rsi_8 > 50 and zScore_8 > 0
            fomoCount := fomoCount + 1
            fomoCount
        else if rsi_8 <= 50 and zScore_8 > 0
            recoveryCount := recoveryCount + 1
            recoveryCount
        else if rsi_8 <= 50 and zScore_8 <= 0
            fearCount := fearCount + 1
            fearCount
        else
            strengthCount := strengthCount + 1
            strengthCount

        if rsi_9 > 50 and zScore_9 > 0
            fomoCount := fomoCount + 1
            fomoCount
        else if rsi_9 <= 50 and zScore_9 > 0
            recoveryCount := recoveryCount + 1
            recoveryCount
        else if rsi_9 <= 50 and zScore_9 <= 0
            fearCount := fearCount + 1
            fearCount
        else
            strengthCount := strengthCount + 1
            strengthCount

        if rsi_10 > 50 and zScore_10 > 0
            fomoCount := fomoCount + 1
            fomoCount
        else if rsi_10 <= 50 and zScore_10 > 0
            recoveryCount := recoveryCount + 1
            recoveryCount
        else if rsi_10 <= 50 and zScore_10 <= 0
            fearCount := fearCount + 1
            fearCount
        else
            strengthCount := strengthCount + 1
            strengthCount

        if rsi_11 > 50 and zScore_11 > 0
            fomoCount := fomoCount + 1
            fomoCount
        else if rsi_11 <= 50 and zScore_11 > 0
            recoveryCount := recoveryCount + 1
            recoveryCount
        else if rsi_11 <= 50 and zScore_11 <= 0
            fearCount := fearCount + 1
            fearCount
        else
            strengthCount := strengthCount + 1
            strengthCount

        if rsi_12 > 50 and zScore_12 > 0
            fomoCount := fomoCount + 1
            fomoCount
        else if rsi_12 <= 50 and zScore_12 > 0
            recoveryCount := recoveryCount + 1
            recoveryCount
        else if rsi_12 <= 50 and zScore_12 <= 0
            fearCount := fearCount + 1
            fearCount
        else
            strengthCount := strengthCount + 1
            strengthCount

        if rsi_13 > 50 and zScore_13 > 0
            fomoCount := fomoCount + 1
            fomoCount
        else if rsi_13 <= 50 and zScore_13 > 0
            recoveryCount := recoveryCount + 1
            recoveryCount
        else if rsi_13 <= 50 and zScore_13 <= 0
            fearCount := fearCount + 1
            fearCount
        else
            strengthCount := strengthCount + 1
            strengthCount

        if rsi_14 > 50 and zScore_14 > 0
            fomoCount := fomoCount + 1
            fomoCount
        else if rsi_14 <= 50 and zScore_14 > 0
            recoveryCount := recoveryCount + 1
            recoveryCount
        else if rsi_14 <= 50 and zScore_14 <= 0
            fearCount := fearCount + 1
            fearCount
        else
            strengthCount := strengthCount + 1
            strengthCount

        // Calculate percentages
        fomoPct = totalAssets > 0 ? fomoCount / totalAssets * 100 : 0
        fearPct = totalAssets > 0 ? fearCount / totalAssets * 100 : 0
        recoveryPct = totalAssets > 0 ? recoveryCount / totalAssets * 100 : 0
        strengthPct = totalAssets > 0 ? strengthCount / totalAssets * 100 : 0

        // Find dominant zone
        maxPct = math.max(fomoPct, fearPct, recoveryPct, strengthPct)
        dominantZone = fomoPct == maxPct ? 'FOMO' : fearPct == maxPct ? 'FEAR' : recoveryPct == maxPct ? 'RECOVERY' : 'STRENGTH'

        // Overall market score (0-100)
        marketScore = strengthPct * 2 + recoveryPct - fearPct - fomoPct * 2 + 50
        marketScore := math.max(0, math.min(100, marketScore))

        // Display metrics
        table.cell(panel, 0, 1, 'Market Score', text_color = #c9d1d9, text_size = size.normal)
        scoreColor = marketScore > 70 ? #00ff88 : marketScore > 30 ? #ffa500 : #ff4444
        table.cell(panel, 1, 1, str.tostring(math.round(marketScore)) + '/100', text_color = scoreColor, text_size = size.large)
        table.merge_cells(panel, 1, 1, 2, 1)

        table.cell(panel, 0, 2, 'Dominant Zone', text_color = #c9d1d9, text_size = size.normal)
        table.cell(panel, 1, 2, dominantZone, text_color = #58a6ff, text_size = size.normal)
        table.merge_cells(panel, 1, 2, 2, 2)

        // Zone distribution
        table.cell(panel, 0, 3, 'Zone Distribution', text_color = #c9d1d9, text_size = size.normal)
        table.merge_cells(panel, 0, 3, 2, 3)

        table.cell(panel, 0, 4, '🔥 FOMO', text_color = #ff4444, text_size = size.small)
        table.cell(panel, 1, 4, str.tostring(math.round(fomoPct, 1)) + '%', text_color = #ff4444, text_size = size.small)
        table.cell(panel, 2, 4, '(' + str.tostring(fomoCount) + ')', text_color = #8b949e, text_size = size.small)

        table.cell(panel, 0, 5, '📈 Recovery', text_color = #ffa500, text_size = size.small)
        table.cell(panel, 1, 5, str.tostring(math.round(recoveryPct, 1)) + '%', text_color = #ffa500, text_size = size.small)
        table.cell(panel, 2, 5, '(' + str.tostring(recoveryCount) + ')', text_color = #8b949e, text_size = size.small)

        table.cell(panel, 0, 6, '❄️ Fear', text_color = #2196f3, text_size = size.small)
        table.cell(panel, 1, 6, str.tostring(math.round(fearPct, 1)) + '%', text_color = #2196f3, text_size = size.small)
        table.cell(panel, 2, 6, '(' + str.tostring(fearCount) + ')', text_color = #8b949e, text_size = size.small)

        table.cell(panel, 0, 7, '💪 Strength', text_color = #00ff88, text_size = size.small)
        table.cell(panel, 1, 7, str.tostring(math.round(strengthPct, 1)) + '%', text_color = #00ff88, text_size = size.small)
        table.cell(panel, 2, 7, '(' + str.tostring(strengthCount) + ')', text_color = #8b949e, text_size = size.small)


// ==================== ALERTS ====================

// Calculate percentages
fomoPct = totalAssets > 0 ? (fomoCount / totalAssets) * 100 : 0
fearPct = totalAssets > 0 ? (fearCount / totalAssets) * 100 : 0
recoveryPct = totalAssets > 0 ? (recoveryCount / totalAssets) * 100 : 0
strengthPct = totalAssets > 0 ? (strengthCount / totalAssets) * 100 : 0


// ==================== ALERTS ====================
if barstate.isconfirmed
    if fomoPct >= crowdingThreshold
        alert("🔥 Crowding Alert: FOMO levels have reached " + str.tostring(math.round(fomoPct, 1)) + "%.", alert.freq_once_per_bar_close)
    if fearPct >= crowdingThreshold
        alert("❄️ Crowding Alert: Fear levels have reached " + str.tostring(math.round(fearPct, 1)) + "%.", alert.freq_once_per_bar_close)
    if recoveryPct >= crowdingThreshold
        alert("📈 Crowding Alert: Recovery levels have reached " + str.tostring(math.round(recoveryPct, 1)) + "%.", alert.freq_once_per_bar_close)
    if strengthPct >= crowdingThreshold
        alert("💪 Crowding Alert: Strength levels have reached " + str.tostring(math.round(strengthPct, 1)) + "%.", alert.freq_once_per_bar_close)

Overview

Crowding Model BullVision calculates the Relative Strength Index and Z-scores across up to 19 assets, mapping them into quadrant zones to identify overbought or oversold crowding. Rendered in a separate pane, it displays relative positioning, visual danger zone thresholds, gradient backgrounds, and an analytical dashboard table tracking market crowding percentages. Users can customize asset tickers, RSI periods, Z-score lookback lengths, and crowding alert levels.

Details

Published by

regalouisei on GitHub

Type

Indicator, Pine Script v6

Draws

Separate pane below the chart

Category

Oscillators & momentum, Screeners & dashboards

Markets

Crypto

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Bar Scaleint150BarScale
Show TOTAL, BTC, ETH, OTHERSbooltrueshowMainAssets
Show Gradient BackgroundbooltrueshowGradientBg
Show Crowding Analytics PanelbooltrueshowCrowdingPanel
RSI Lengthint14rsi_length
Z-score lookbackint90Z_score_L
Crowding Alert Threshold %float40.0crowdingThreshold
Show Quadrant LabelsbooltrueshowQuadrantLabels
Highlight Danger ZonesbooltrueshowDangerZones
Danger RSI Highfloat70.0dangerRSIHigh
Danger RSI Lowfloat30.0dangerRSILow
MARKET INDEXsymbolCRYPTOCAP:TOTALsymbolINDEX
Show all 40 settings
SettingTypeDefaultVariable
SECONDARY INDEXsymbolCRYPTOCAP:OTHERSsymbolINDEX2
MAIN ASSET symbolINDEX:BTCUSDsymbolMAIN
SECOND MAIN ASSETsymbolINDEX:ETHUSDsymbolMAIN2
Asset 1symbolCRYPTO:BNBUSDsymbol1
Asset 2 symbolCRYPTO:SOLUSDsymbol2
Asset 3 symbolCRYPTO:XRPUSDsymbol3
Asset 4 symbolCRYPTO:ADAUSDsymbol4
Asset 5 symbolCRYPTO:DOGEUSDsymbol5
Asset 6 symbolCRYPTO:AVAXUSDsymbol6
Asset 7 symbolCRYPTO:SHIBUSDsymbol7
Asset 8 symbolCRYPTO:TRXUSDsymbol8
Asset 9 symbolCRYPTO:DOTUSDsymbol9
Asset 10 symbolCRYPTO:LINKUSDsymbol10
Asset 11 symbolCRYPTO:MATICUSDsymbol11
Asset 12 symbolCRYPTO:UNIUSDsymbol12
Asset 13 symbolCRYPTO:TONUSDsymbol13
Asset 14 symbolCRYPTO:BCHUSDsymbol14
Asset 15 symbolCRYPTO:LTCUSDsymbol15
Asset 16 symbolCRYPTO:ICPUSDsymbol16
Asset 17 symbolCRYPTO:FILUSDsymbol17
Asset 18 symbolCRYPTO:ETCUSDsymbol18
Asset 19 symbolCRYPTO:ATOMUSDsymbol19
Asset 20 symbolCRYPTO:IMXUSDsymbol20
Asset 21 symbolCRYPTO:NEARUSDsymbol21
Asset 22 symbolCRYPTO:LEOUSDsymbol22
Asset 23 symbolCOINBASE:STXUSDsymbol23
Asset 24 symbolCOINBASE:APTUSDsymbol24
Asset 25 symbolKUCOIN:TAOUSDTsymbol25
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

This indicator scans a pasted list of symbols for RSI directional momentum and shows matching long and short signals in a table in a separate pane. The user chooses continuous break, continuous retracement, flip break, flip retracement, divergence, or hidden d

Indicator v6 Oscillators & momentumDivergence
Updated 1 year ago · MPL-2.0 GitHub repository of Momentum Setup - RSI Directional Momentum Scanner
261 stars

This indicator plots the RSI oscillator on the main chart and displays its value distribution in a table positioned at the top right. The script calculates the relative strength index using the input source and length, then plots horizontal lines at 0, 50, and

Indicator v4 Oscillators & momentumScreeners & dashboards
Updated 4 years ago · None stated GitHub repository of Tables-003 Oscillator Distribution

Market Speedometer

by TradersPost
218 stars

Market Speedometer plots a 0-100 market speed reading in a separate pane. It measures movement by bar-to-bar change, true range, or a short average of recent bars, then ranks that movement against ATR and a percentile lookback. An EMA smooths the reading, and

Indicator v6 Volatility & bandsOscillators & momentum
Updated 3 months ago · None stated GitHub repository of Market Speedometer

KamaFama

by Mastaaa1987
141 stars

KamaFama is an indicator that translates a Freqtrade trading strategy into Pine Script for visualization. It combines Kaufman Adaptive Moving Average (KAMA), MAMA/FAMA calculations derived via Hilbert Transform, Williams %R, and correlation trend filters to ev

Indicator v6 Moving averagesOscillators & momentum
Updated 6 weeks ago · MIT GitHub repository of KamaFama
114 stars

Calculates normalized reversal metrics across up to ten Forex currency pairs using user-selected moving average methods, including HarmonicMA, EMA, SMA, or WMA. The indicator identifies overbought, oversold, and mean-crossing conditions using a configurable th

Indicator v4 Screeners & dashboardsMean reversion
Updated 1 year ago · None stated GitHub repository of Multi-Pair Trend Reversal Widget

More indicators

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers