Scan to open on your phone
Point a camera at the QR code - it opens this exact paste, no app needed.
https://codepastes.com/zzgsp8trsjh2d4rvheatmapPlain Text
//@version=6
indicator("Mini Heatmap - 7 Big Techs", shorttitle="Heatmap", overlay=true, max_labels_count=100)
// =====================================================================
// Painel fixo no gráfico mostrando a variação % do dia (igual ao Stock
// Heatmap do TradingView) de até 7 ativos escolhidos por você.
// O Heatmap nativo do TradingView não deixa filtrar só alguns tickers,
// ele é preso ao índice inteiro. Esse indicador resolve isso: você
// escolhe exatamente quem quer ver, plugado direto no seu gráfico.
// =====================================================================
// Peso (%) é o quanto cada ativo pesa dentro do Nasdaq 100 (carteira do QQQ).
// O painel ordena sozinho do mais poderoso pro menos poderoso usando esse número.
// Atualize esses valores de vez em quando, o peso muda com o tempo (fonte: holdings do QQQ).
grpAtivos = "Ativos (padrão: pesos aproximados do Nasdaq 100, ajuste quando quiser)"
sym1 = input.symbol("NASDAQ:NVDA", "Ativo 1", group=grpAtivos, inline="a1")
w1 = input.float(8.7, "Peso %", group=grpAtivos, inline="a1")
sym2 = input.symbol("NASDAQ:AAPL", "Ativo 2", group=grpAtivos, inline="a2")
w2 = input.float(7.6, "Peso %", group=grpAtivos, inline="a2")
sym3 = input.symbol("NASDAQ:MSFT", "Ativo 3", group=grpAtivos, inline="a3")
w3 = input.float(5.6, "Peso %", group=grpAtivos, inline="a3")
sym4 = input.symbol("NASDAQ:AMZN", "Ativo 4", group=grpAtivos, inline="a4")
w4 = input.float(4.6, "Peso %", group=grpAtivos, inline="a4")
sym5 = input.symbol("NASDAQ:TSLA", "Ativo 5", group=grpAtivos, inline="a5")
w5 = input.float(3.8, "Peso %", group=grpAtivos, inline="a5")
sym6 = input.symbol("NASDAQ:META", "Ativo 6", group=grpAtivos, inline="a6")
w6 = input.float(3.5, "Peso %", group=grpAtivos, inline="a6")
sym7 = input.symbol("NASDAQ:GOOGL", "Ativo 7", group=grpAtivos, inline="a7")
w7 = input.float(3.4, "Peso %", group=grpAtivos, inline="a7")
grpVisual = "Visual"
posOpt = input.string("Superior Direito", "Posição do painel", options=["Superior Direito", "Superior Esquerdo", "Superior Centro", "Inferior Direito", "Inferior Esquerdo", "Inferior Centro", "Meio Direito", "Meio Esquerdo"], group=grpVisual)
cols = input.int(4, "Colunas", minval=1, maxval=7, group=grpVisual, tooltip="Quantos quadrados por linha. Ex: 4 colunas com 7 ativos vira 4+3")
txtSizeOpt = input.string("Normal", "Tamanho do texto", options=["Minúsculo", "Pequeno", "Normal", "Grande"], group=grpVisual)
maxPct = input.float(3.0, "Saturação máxima (%)", minval=0.1, group=grpVisual, tooltip="A partir de quantos % de variação a cor fica no verde/vermelho mais forte")
showTicker = input.bool(true, "Mostrar ticker", group=grpVisual)
showPct = input.bool(true, "Mostrar variação %", group=grpVisual)
showWeight = input.bool(true, "Mostrar peso %", group=grpVisual)
getPosition(p) =>
result = switch p
"Superior Esquerdo" => position.top_left
"Superior Centro" => position.top_center
"Inferior Direito" => position.bottom_right
"Inferior Esquerdo" => position.bottom_left
"Inferior Centro" => position.bottom_center
"Meio Direito" => position.middle_right
"Meio Esquerdo" => position.middle_left
=> position.top_right
result
getTxtSize(s) =>
s == "Minúsculo" ? size.tiny : s == "Pequeno" ? size.small : s == "Grande" ? size.large : size.normal
// variação % do dia (igual "Change 1D, %" do heatmap), calculada no contexto diário
f_change(sym) =>
request.security(sym, "D", (close - close[1]) / close[1] * 100, barmerge.gaps_off, barmerge.lookahead_off)
f_ticker(sym) =>
parts = str.split(sym, ":")
array.size(parts) > 1 ? array.get(parts, array.size(parts) - 1) : sym
f_color(pct) =>
t = math.min(math.abs(pct) / maxPct, 1.0)
pct >= 0 ? color.from_gradient(t, 0, 1, color.new(color.green, 80), color.new(color.green, 5)) : color.from_gradient(t, 0, 1, color.new(color.red, 80), color.new(color.red, 5))
if barstate.islast
symbols = array.from(sym1, sym2, sym3, sym4, sym5, sym6, sym7)
weights = array.from(w1, w2, w3, w4, w5, w6, w7)
n = array.size(symbols)
rows = int(math.ceil(n / cols))
// ordena do mais poderoso (maior peso) pro menos poderoso
rankIdx = array.sort_indices(array.copy(weights), order.descending)
var table tbl = table.new(getPosition(posOpt), cols, rows, border_width=1, border_color=color.new(color.gray, 50), frame_width=1, frame_color=color.new(color.gray, 50))
txtSz = getTxtSize(txtSizeOpt)
for i = 0 to n - 1
idx = array.get(rankIdx, i)
s = array.get(symbols, idx)
w = array.get(weights, idx)
pct = f_change(s)
tk = f_ticker(s)
r = int(math.floor(i / cols))
c = int(i % cols)
line1 = showTicker ? tk : ""
line2 = showWeight ? str.tostring(w, "#.#") + "%" : ""
line3 = showPct ? (pct >= 0 ? "+" : "") + str.tostring(pct, "#.##") + "%" : ""
txt = line1
txt := txt + (line2 != "" ? "\n" + line2 : "")
txt := txt + (line3 != "" ? "\n" + line3 : "")
table.cell(tbl, c, r, txt, text_color=color.white, bgcolor=f_color(pct), text_size=txtSz)5,184 chars · codepastes.com