Dejo aquí la traducción de un indicador de tradingview que me parece interesante.
https://es.tradingview.com/v/yXJBwibN/
Este es el código traducido (tenéis la explicación en la librería de códigos)
Liquidity Pools
//----------------------------------------------
//PRC_Liquidity Pools [LuxAlgo]
//Pools de liquidez: niveles tocados N veces + volumen atrapado
//version = 1
//02.06.2026
//Ivan Gonzalez @ www.prorealcode.com
//Sharing ProRealTime knowledge
//----------------------------------------------
defparam drawonlastbaronly = true
// === INPUTS ===
cNum = 2 // Zone Contact Amount (contactos minimos para validar el pool)
gapCount = 5 // Bars Required Between Each Contact
waitBars = 10 // Confirmation Bars (espera antes de dibujar la zona)
volTog = 1 // 1 = mostrar etiquetas de volumen
maxZones = 10 // cap de zonas vivas por lado
// === COLORES (RGB) ===
bullR = 8
bullG = 153
bullB = 129
bearR = 242
bearG = 54
bearB = 69
MAXZ = 20 // cota superior de slots del pool por lado
// === VELA ACTUAL ===
cTop = max(open, close)
cBot = min(open, close)
// === ESTADO PERSISTENTE (init en la primera barra) ===
// Solo se conservan los campos del UDT 'data' realmente usados:
// referencia ALTA (resistencia): hstH (mecha=top caja), hstT (cuerpo=nivel/linea), hstBi (x izq)
// referencia BAJA (soporte): lstB (cuerpo=nivel/linea), lstL (mecha=bottom caja), lstBi (x izq)
if barindex = 0 then
hstH = high
hstT = cTop
hstBi = barindex
lstB = cBot
lstL = low
lstBi = barindex
hCount = 0
lCount = 0
lastHwick = barindex
lastLwick = barindex
hiVol = 0
loVol = 0
bsHw = 0
bsLw = 0
endif
// === 1. RESET DE REFERENCIA ALTA ===
if high > hstH and (cTop > hstH or cTop < hstT) then
if hCount > 1 then
lstB = cBot
lstL = low
lstBi = barindex
loVol = 0
lCount = 0
endif
hstH = high
hstT = cTop
hstBi = barindex
hiVol = 0
hCount = 1
lastHwick = barindex
endif
// === 2. RESET DE REFERENCIA BAJA ===
if low < lstL and (cBot < lstL or cBot > lstB) then
if lCount > 1 then
hstH = high
hstT = cTop
hstBi = barindex
hiVol = 0
hCount = 0
endif
lstB = cBot
lstL = low
lstBi = barindex
loVol = 0
lCount = 1
lastLwick = barindex
endif
// === 3. CONTEO DE CONTACTOS ===
hWick = 0
if high > hstT and cTop <= hstT then
hWick = 1
endif
lWick = 0
if low < lstB and cBot >= lstB then
lWick = 1
endif
// Se confirma el contacto una barra despues.
if barindex > 2 and hWick[1] = 1 and hstT[1] = hstT[2] and bsHw[1] > gapCount then
hCount = hCount + 1
lastHwick = barindex - 1
endif
if barindex > 2 and lWick[1] = 1 and lstB[1] = lstB[2] and bsLw[1] > gapCount then
lCount = lCount + 1
lastLwick = barindex - 1
endif
// Barras desde el ultimo contacto
bsHw = abs(lastHwick - barindex)
bsLw = abs(lastLwick - barindex)
// === 4. TRACKING DE EXTREMOS ===
if high > hstH then
hstH = high
endif
if low < lstL then
lstL = low
endif
// === 5. VOLUMEN ATRAPADO ===
rng = high - low
if rng > 0 then
hstVol = max(high - hstT, 0) / rng * volume
lstVol = max(lstB - low, 0) / rng * volume
else
hstVol = 0
lstVol = 0
endif
hiVol = hiVol + hstVol
loVol = loVol + lstVol
// === 6. CONFIRMACION + CREACION ZONA BEAR (resistencia) ===
bearTrig = 0
if hCount >= cNum and bsHw > waitBars and bsHw[1] <= waitBars and close < hstT then
bearTrig = 1
endif
if bearTrig = 1 then
// Merge: si el nivel cae dentro de una zona bear viva, fusiona en vez de duplicar.
mergedB = 0
for i = 0 to MAXZ - 1 do
if $bzAct[i] = 1 and mergedB = 0 then
if hstT <= $bzTop[i] and hstT >= $bzLvl[i] then
if hstH > $bzTop[i] then
$bzTop[i] = hstH
endif
$bzRight[i] = barindex
$bzVol[i] = $bzVol[i] + hiVol
$bzBorn[i] = barindex
mergedB = 1
endif
endif
next
// Si no fusiona: slot libre o, si se alcanzo el cap, eviccion FIFO (menor born).
if mergedB = 0 then
slot = -1
cnt = 0
oldIdx = -1
oldBorn = 0
for i = 0 to MAXZ - 1 do
if $bzAct[i] = 1 then
cnt = cnt + 1
if oldIdx = -1 or $bzBorn[i] < oldBorn then
oldBorn = $bzBorn[i]
oldIdx = i
endif
else
if slot = -1 then
slot = i
endif
endif
next
if cnt >= maxZones then
slot = oldIdx
endif
if slot = -1 then
slot = oldIdx
endif
$bzLvl[slot] = hstT
$bzTop[slot] = hstH
$bzLeft[slot] = hstBi
$bzRight[slot] = barindex
$bzVol[slot] = hiVol
$bzAct[slot] = 1
$bzState[slot] = 0
$bzBorn[slot] = barindex
endif
endif
// === 7. CONFIRMACION + CREACION ZONA BULL (soporte) ===
bullTrig = 0
if lCount >= cNum and bsLw > waitBars and bsLw[1] <= waitBars and close > lstB then
bullTrig = 1
endif
if bullTrig = 1 then
mergedL = 0
for i = 0 to MAXZ - 1 do
if $lzAct[i] = 1 and mergedL = 0 then
if lstB >= $lzBot[i] and lstB <= $lzLvl[i] then
if lstL < $lzBot[i] then
$lzBot[i] = lstL
endif
$lzRight[i] = barindex
$lzVol[i] = $lzVol[i] + loVol
$lzBorn[i] = barindex
mergedL = 1
endif
endif
next
if mergedL = 0 then
slot = -1
cnt = 0
oldIdx = -1
oldBorn = 0
for i = 0 to MAXZ - 1 do
if $lzAct[i] = 1 then
cnt = cnt + 1
if oldIdx = -1 or $lzBorn[i] < oldBorn then
oldBorn = $lzBorn[i]
oldIdx = i
endif
else
if slot = -1 then
slot = i
endif
endif
next
if cnt >= maxZones then
slot = oldIdx
endif
if slot = -1 then
slot = oldIdx
endif
$lzLvl[slot] = lstB
$lzBot[slot] = lstL
$lzLeft[slot] = lstBi
$lzRight[slot] = barindex
$lzVol[slot] = loVol
$lzAct[slot] = 1
$lzState[slot] = 0
$lzBorn[slot] = barindex
endif
endif
// === 8. MITIGACION / DELECION ===
// Bear: barrida cuando el cierre supera el extremo superior de la zona.
for i = 0 to MAXZ - 1 do
if $bzAct[i] = 1 then
if close > $bzTop[i] then
if $bzState[i] < 0 then
$bzAct[i] = 0
endif
$bzState[i] = $bzState[i] - 1
else
$bzState[i] = 0
endif
endif
next
// Bull: barrida cuando el cierre pierde el extremo inferior de la zona.
for i = 0 to MAXZ - 1 do
if $lzAct[i] = 1 then
if close < $lzBot[i] then
if $lzState[i] < 0 then
$lzAct[i] = 0
endif
$lzState[i] = $lzState[i] - 1
else
$lzState[i] = 0
endif
endif
next
// === 9. RENDER (solo en la ultima barra) ===
if islastbarupdate then
// --- ZONAS BEAR (resistencia / liquidez en maximos) ---
for i = 0 to MAXZ - 1 do
if $bzAct[i] = 1 then
lvl = $bzLvl[i]
topY = $bzTop[i]
lft = $bzLeft[i]
rgt = $bzRight[i]
drawrectangle(lft, topY, rgt, lvl) coloured(bearR, bearG, bearB, 0) fillcolor(bearR, bearG, bearB, 51)
drawsegment(lft, lvl, barindex, lvl) coloured(bearR, bearG, bearB) style(line, 1)
if volTog = 1 then
vv = $bzVol[i]
if vv >= 1000000 then
vShow = round(vv / 100000) / 10
drawtext("#vShow#M", barindex + 3, lvl) coloured(bearR, bearG, bearB)
elsif vv >= 1000 then
vShow = round(vv / 100) / 10
drawtext("#vShow#K", barindex + 3, lvl) coloured(bearR, bearG, bearB)
else
vShow = round(vv)
drawtext("#vShow#", barindex + 3, lvl) coloured(bearR, bearG, bearB)
endif
endif
endif
next
// --- ZONAS BULL (soporte / liquidez en minimos) ---
for i = 0 to MAXZ - 1 do
if $lzAct[i] = 1 then
lvl = $lzLvl[i]
botY = $lzBot[i]
lft = $lzLeft[i]
rgt = $lzRight[i]
drawrectangle(lft, lvl, rgt, botY) coloured(bullR, bullG, bullB, 0) fillcolor(bullR, bullG, bullB, 51)
drawsegment(lft, lvl, barindex, lvl) coloured(bullR, bullG, bullB) style(line, 1)
if volTog = 1 then
vv = $lzVol[i]
if vv >= 1000000 then
vShow = round(vv / 100000) / 10
drawtext("#vShow#M", barindex + 3, lvl) coloured(bullR, bullG, bullB)
elsif vv >= 1000 then
vShow = round(vv / 100) / 10
drawtext("#vShow#K", barindex + 3, lvl) coloured(bullR, bullG, bullB)
else
vShow = round(vv)
drawtext("#vShow#", barindex + 3, lvl) coloured(bullR, bullG, bullB)
endif
endif
endif
next
endif
return