ProRealCode - Trading & Coding with ProRealTime™
Buenas tardes, me gustaría obtener el siguiente indicador de tradingview a Prorealtime, he estado buscando por si ya estuviera dentro de la biblioteca de prorealtime pero no lo he encontrado, os agradecería vuestro trabajo, gracias:
// © AlgoAlpha
// This Source Code is subject to the Mozilla Public License 2.0
// https://mozilla.org/MPL/2.0/
//@version=6
indicator(“Smart Money Breakout Channels [AlgoAlpha]”, “AlgoAlpha – Breakout Channels”, overlay=true, max_boxes_count = 500)
import TradingView/ta/10
// ============================================================================
// INPUTS
// ============================================================================
overlap = input.bool(false, “Nested Channels”, group = “Main Settings”, tooltip=”When enabled, allows multiple channels to overlap. When disabled, only one channel can exist at a time. Overlapping channels can show multiple breakout levels simultaneously.”)
strong = input.bool(true, “Strong Closes Only”, “When enabled, breakouts only trigger when more than 50% of the candle body is outside the channel. This reduces false signals from wicks. When disabled, any price movement outside the channel triggers a breakout.”, group = “Main Settings”)
length_ = input.int(100, title=”Normalization Length”, minval=1, group = “Main Settings”, tooltip=”The number of bars used to calculate the highest high and lowest low for price normalization. Higher values create more stable normalization but may be less responsive to recent price changes.”)
length = input.int(14, “Box Detection Length”, minval=1, group = “Main Settings”, tooltip=”The number of bars used to detect channel formation patterns. Lower values create more frequent channels but may be more sensitive to noise. Higher values create fewer but potentially more significant channels.”)
shw_vol = input.bool(true, “Show Volume Analysis”, “When enabled, displays volume analysis as candle-like bars within the channel. This helps identify volume patterns that may precede breakouts.”, group = “Volume Analysis”)
vol_mode = input.string(“Comparison”, “Volume Display Mode”, options=[“Volume”, “Comparison”, “Delta”], group=”Volume Analysis”, tooltip=”Volume: Shows total volume as symmetrical bars. Comparison: Shows up volume above midline, down volume below. Delta: Shows net volume delta (positive above, negative below midline).”)
tf = input.timeframe(“1”, “Volume Delta Timeframe Source”, group = “Volume Analysis”, tooltip=”The timeframe used to calculate volume delta data. Lower timeframes provide more granular volume analysis but may be noisier.”)
vol_scale = input.float(0.5, “Volume Scale”, minval=0.1, maxval=2.0, step=0.1, group=”Volume Analysis”, tooltip=”Adjusts the height of volume bars relative to channel size. Higher values make volume bars more prominent, lower values make them more subtle.”)
text_size = input.string(“Tiny”, “Volume Text Size”, options=[“Tiny”,”Small”,”Medium”,”Large”], group=”Appearance”, tooltip=”Size of the volume text at the corner of the channels.”)
green = input.color(#00ffbb, title = “Bullish Colour”, group = “Appearance”, tooltip = “Primary colour for bullish visual elements. Adjust for preferred palette – affects bars, fills, and labels when momentum is positive.”)
red = input.color(#ff1100, title = “Bearish Colour”, group = “Appearance”, tooltip = “Primary colour for bearish visual elements. Adjust for preferred palette – affects bars, fills, and labels when momentum is negative.”)
// ============================================================================
// VARIABLES
// ============================================================================
var boxes = array.new_box()
var boxes_u = array.new_box()
var boxes_l = array.new_box()
var line[] gaugeLines = array.new<line>()
var label gaugeLabel = na
var line[] centerLines = array.new<line>()
// ============================================================================
// FUNCTIONS
// ============================================================================
textSize(text_size) =>
switch text_size
“Tiny” => size.tiny
“Small” => size.small
“Medium”=> size.normal
“Large” => size.large
f_can_create(float tNew, float bNew) =>
ok = true
if boxes.size() > 0
for j = 0 to boxes.size()-1
if (tNew > boxes.get(j).get_bottom()) and (bNew < boxes.get(j).get_top())
ok := false
break
ok
getVolumeTransparency(float vol, float smoothed_vol) =>
if vol_mode == “Volume”
float vol_ratio = vol / smoothed_vol
float transparency = math.max(20, math.min(80, 80 – (vol_ratio – 0.5) * 40))
transparency
else
0
// ============================================================================
// CALCULATIONS
// ============================================================================
lowestLow = ta.lowest(low, length_)
highestHigh = ta.highest(high, length_)
normalizedPrice = (close – lowestLow) / (highestHigh – lowestLow)
vol = ta.stdev(normalizedPrice, 14)
upper = (ta.highestbars(vol, length + 1) + length)/length
lower = (ta.lowestbars(vol, length + 1) + length)/length
upbreak = 0.0
downbreak = 0.0
duration = math.max(nz(ta.barssince(ta.crossover(lower,upper))), 1)
h = ta.highest(duration)
l = ta.lowest(duration)
[uv, dv, vold] = ta.requestUpAndDownVolume(tf)
var hvold = vold
var lvold = vold
if ta.crossover(lower, upper)
hvold := vold
lvold := vold
if vold > hvold
hvold := vold
if vold < lvold
lvold := vold
smoothedvol = ta.sma(volume, 20)
vola = ta.atr(length)/2
bool newChannelFormed = false
bool bullishBreakout = false
bool bearishBreakout = false
if ta.crossover(upper, lower) and duration > 10
if overlap or f_can_create(h, l)
boxes.unshift(box.new(bar_index-duration, h, bar_index, l, bgcolor = color.new(chart.fg_color, 90), border_color = na))
boxes_u.unshift(box.new(bar_index-duration, h, bar_index, h-vola, bgcolor = color.new(red, 70), border_color = na))
boxes_l.unshift(box.new(bar_index-duration, l+vola, bar_index, l, bgcolor = color.new(green, 70), border_color = na))
float centerY = (h + l) / 2
centerLines.unshift(line.new(bar_index-duration, centerY, bar_index, centerY, color = color.new(chart.fg_color, 50), width = 1, style = line.style_dashed))
newChannelFormed := true
if boxes.size() > 0
for i = 0 to boxes.size()-1
if ((strong ? math.avg(close, open) : close) > boxes.get(i).get_top())
upbreak := boxes.get(i).get_bottom()
boxes.remove(i)
boxes_u.remove(i)
boxes_l.remove(i)
centerLines.remove(i)
bullishBreakout := true
else if ((strong ? math.avg(close, open) : close) < boxes.get(i).get_bottom())
downbreak := boxes.get(i).get_top()
boxes.remove(i)
boxes_u.remove(i)
boxes_l.remove(i)
centerLines.remove(i)
bearishBreakout := true
else
boxes.get(i).set_right(bar_index)
boxes_u.get(i).set_right(bar_index)
boxes_l.get(i).set_right(bar_index)
centerLines.get(i).set_x2(bar_index)
// Add volume text to appropriate box based on price position
float boxMidline = (boxes.get(i).get_top() + boxes.get(i).get_bottom()) / 2
float currentPrice = strong ? math.avg(close, open) : close
string volText = “”
if vol_mode == “Volume”
volText := str.tostring(math.round(volume / 1000, 1)) + “K”
else if vol_mode == “Comparison”
volText := str.tostring(math.round(uv / 1000, 1)) + “K/” + str.tostring(math.round(dv / 1000, 1)) + “K”
else if vol_mode == “Delta”
volText := str.tostring(math.round(vold / 1000, 1)) + “K”
if currentPrice > boxMidline
// Price is above midline, add text to lower (green) box
boxes_l.get(i).set_text(volText)
boxes_l.get(i).set_text_halign(text.align_right)
boxes_l.get(i).set_text_color(color.new(chart.fg_color, 30))
boxes_l.get(i).set_text_size(textSize(text_size))
boxes_u.get(i).set_text(“”)
else
// Price is below midline, add text to upper (red) box
boxes_u.get(i).set_text(volText)
boxes_u.get(i).set_text_halign(text.align_right)
boxes_u.get(i).set_text_color(color.new(chart.fg_color, 30))
boxes_u.get(i).set_text_size(textSize(text_size))
boxes_l.get(i).set_text(“”)
float currentMidline = na
float channelHeight = na
if boxes.size() > 0
float topBound = boxes.get(0).get_top()
float bottomBound = boxes.get(0).get_bottom()
currentMidline := (topBound + bottomBound) / 2
channelHeight := (topBound – bottomBound) * vol_scale
float vol_upper_open = na
float vol_upper_high = na
float vol_upper_low = na
float vol_upper_close = na
float vol_lower_open = na
float vol_lower_high = na
float vol_lower_low = na
float vol_lower_close = na
if not na(currentMidline) and not na(channelHeight) and shw_vol
if vol_mode == “Volume”
float vol_height = (volume / smoothedvol) * (channelHeight / 4)
vol_upper_open := currentMidline
vol_upper_close := currentMidline + vol_height
vol_upper_high := currentMidline + vol_height
vol_upper_low := currentMidline
vol_lower_open := currentMidline
vol_lower_close := currentMidline – vol_height
vol_lower_high := currentMidline
vol_lower_low := currentMidline – vol_height
else if vol_mode == “Comparison”
float uv_height = na(uv) ? 0 : (uv / smoothedvol) * (channelHeight / 4)
float dv_height = na(dv) ? 0 : (dv / smoothedvol) * (channelHeight / 4)
vol_upper_open := currentMidline
vol_upper_close := currentMidline + uv_height
vol_upper_high := currentMidline + uv_height
vol_upper_low := currentMidline
vol_lower_open := currentMidline
vol_lower_close := currentMidline + dv_height
vol_lower_high := currentMidline
vol_lower_low := currentMidline + dv_height
else if vol_mode == “Delta”
float delta_height = na(vold) ? 0 : math.abs(vold / smoothedvol) * (channelHeight / 4)
if vold >= 0
vol_upper_open := currentMidline
vol_upper_close := currentMidline + delta_height
vol_upper_high := currentMidline + delta_height
vol_upper_low := currentMidline
vol_lower_open := currentMidline
vol_lower_close := currentMidline
vol_lower_high := currentMidline
vol_lower_low := currentMidline
else
vol_upper_open := currentMidline
vol_upper_close := currentMidline
vol_upper_high := currentMidline
vol_upper_low := currentMidline
vol_lower_open := currentMidline
vol_lower_close := currentMidline – delta_height
vol_lower_high := currentMidline
vol_lower_low := currentMidline – delta_height
color upperColor = na
color lowerColor = na
if vol_mode == “Volume”
float transparency = getVolumeTransparency(volume, smoothedvol)
upperColor := color.new(chart.fg_color, transparency)
lowerColor := color.new(chart.fg_color, transparency)
else
upperColor := green
lowerColor := red
// ============================================================================
// VISUALS
// ============================================================================
plotshape(upbreak != 0 ? upbreak : na, “Bullish Breakout Signal”, shape.labelup, location.absolute, green, text = “▲”, textcolor = chart.fg_color)
plotshape(downbreak != 0 ? downbreak : na, “Bearish Breakout Signal”, shape.labeldown, location.absolute, red, text = “▼”, textcolor = chart.fg_color)
plotcandle(vol_upper_open, vol_upper_high, vol_upper_low, vol_upper_close, color=upperColor, wickcolor=upperColor, bordercolor=upperColor)
plotcandle(vol_lower_open, vol_lower_high, vol_lower_low, vol_lower_close, color=lowerColor, wickcolor=lowerColor, bordercolor=lowerColor)
volumeAvailable = not na(volume)
if barstate.islast
bool channelActive = boxes.size() > 0 and upbreak == 0 and downbreak == 0
if array.size(gaugeLines) > 0
for ln in gaugeLines
ln.delete()
gaugeLines.clear()
if not na(gaugeLabel)
gaugeLabel.delete()
gaugeLabel := na
if channelActive
float topBound = boxes.get(0).get_top()
float bottomBound = boxes.get(0).get_bottom()
if not na(topBound) and not na(bottomBound) and topBound != bottomBound
int segments = 21
float segLen = (topBound – bottomBound) / segments
for i = 0 to segments – 1
float y1 = topBound – i * segLen
float y2 = topBound – (i + 1) * segLen
color segCol = color.from_gradient(y1, bottomBound, topBound, red, green)
line ln = line.new(x1 = bar_index + 2,
y1 = y1,
x2 = bar_index + 2,
y2 = y2,
color = segCol,
width = 4)
gaugeLines.unshift(ln)
float delvol = -100*2*((vold-lvold)/(hvold-lvold)-0.5)
delvol := math.max(math.min(delvol, 100), -100)
float pointerPos = topBound – ((delvol + 100) / 200) * (topBound – bottomBound)
gaugeLabel := label.new(x = bar_index + 3,
y = pointerPos,
text = “◀”,
color = na,
textcolor = chart.fg_color,
size = size.small,
style = label.style_label_left)
if not volumeAvailable
var gaugeWarnTable = table.new(position = position.top_right, columns = 1, rows = 1, bgcolor = red, border_width = 1, border_color = chart.fg_color, frame_color = chart.fg_color, frame_width = 1)
table.cell(gaugeWarnTable, 0, 0, “Volume not availablenGauge may not work as expected”, text_color = chart.fg_color, text_halign = text.align_center, text_size = size.small)
// ============================================================================
// ALERTS
// ============================================================================
alertcondition(newChannelFormed, “New Channel Formation”, “A new breakout channel has been formed”)
alertcondition(bullishBreakout, “Bullish Breakout”, “Price has broken out above the channel (bullish signal)”)
alertcondition(bearishBreakout, “Bearish Breakout”, “Price has broken out below the channel (bearish signal)”)
Hola. Por favor no duplique mensajes en el foro.
Este es el lugar correcto para solicitar traducciones de indicadores de tradingview a prorealtime.
Voy a eliminar el mensaje duplicado.
Aqui está el indicador:
//---------------------------------------------------
// PRC_Smart Money Breakout Channels (by AlgoAlpha)
// version = 0
// 26.02.2026
// Iván González @ www.prorealcode.com
// Sharing ProRealTime knowledge
//---------------------------------------------------
defparam drawonlastbaronly = true
//---------------------------------------------------
// ===== PARÁMETROS =====
//---------------------------------------------------
overlapMode = 0 // 0=un canal a la vez, 1=canales anidados
strongClose = 1 // 1=cierres fuertes (>50% cuerpo fuera), 0=cualquier cierre
normLength = 100 // Longitud normalización precio
boxLength = 14 // Longitud detección canal
minDuration = 10 // Duración mínima consolidación
showGauge = 1 // 1=mostrar gauge, 0=ocultar
maxCh = 30 // Máximo canales almacenados (FIFO: siempre los recientes)
//---------------------------------------------------
// ===== NORMALIZACIÓN Y VOLATILIDAD =====
//---------------------------------------------------
lowestL = lowest[normLength](low)
highestH = highest[normLength](high)
IF highestH - lowestL <> 0 THEN
normPrice = (close - lowestL) / (highestH - lowestL)
ELSE
normPrice = 0.5
ENDIF
volat = std[14](normPrice)
//---------------------------------------------------
// Detección máximo/mínimo volatilidad
//---------------------------------------------------
hbVol = HighestBars[boxLength + 1](volat)
lbVol = LowestBars[boxLength + 1](volat)
upperDet = (boxLength - hbVol) / boxLength
lowerDet = (boxLength - lbVol) / boxLength
//---------------------------------------------------
// ===== DURACIÓN CONSOLIDACIÓN =====
//---------------------------------------------------
ONCE sinceLCross = 999
IF lowerDet crosses over upperDet THEN
sinceLCross = 0
ELSE
sinceLCross = sinceLCross + 1
ENDIF
dur = max(sinceLCross, 1)
// Rango del periodo de consolidación
chanH = highest[dur](high)
chanL = lowest[dur](low)
//---------------------------------------------------
// ===== ESTIMACIÓN VOLUME DELTA =====
//---------------------------------------------------
IF high - low <> 0 THEN
upVol = volume * (close - low) / (high - low)
downVol = volume * (high - close) / (high - low)
ELSE
upVol = volume / 2
downVol = volume / 2
ENDIF
volDelta = upVol - downVol
ONCE hvold = 0
ONCE lvold = 0
IF lowerDet crosses over upperDet THEN
hvold = volDelta
lvold = volDelta
ENDIF
IF volDelta > hvold THEN
hvold = volDelta
ENDIF
IF volDelta < lvold THEN
lvold = volDelta
ENDIF
//---------------------------------------------------
// ===== ALMACENAMIENTO CANALES =====
//---------------------------------------------------
ONCE numCh = 0
// $chTop[i], $chBot[i] = techo/suelo canal
// $chLeft[i], $chRight[i] = barindex inicio/fin
// $chActive[i] = 1 activo, 0 roto
// $chDir[i] = 0 activo, 1 bull break, -1 bear break
// $chBrkBar[i] = barindex de ruptura
// $chBrkPrc[i] = precio señal ruptura
//---------------------------------------------------
// ===== DETECCIÓN NUEVO CANAL =====
//---------------------------------------------------
IF upperDet crosses over lowerDet AND dur > minDuration THEN
canCreate = 1
IF overlapMode = 0 AND numCh > 0 THEN
checkDone = 0
FOR ic = 0 TO numCh - 1 DO
IF checkDone = 0 AND $chActive[ic] = 1 THEN
IF chanH > $chBot[ic] AND chanL < $chTop[ic] THEN
canCreate = 0
checkDone = 1
ENDIF
ENDIF
NEXT
ENDIF
IF canCreate = 1 THEN
// FIFO: si lleno, eliminar el más antiguo y desplazar todo
IF numCh >= maxCh THEN
FOR sh = 0 TO maxCh - 2 DO
$chTop[sh] = $chTop[sh + 1]
$chBot[sh] = $chBot[sh + 1]
$chLeft[sh] = $chLeft[sh + 1]
$chRight[sh] = $chRight[sh + 1]
$chActive[sh] = $chActive[sh + 1]
$chDir[sh] = $chDir[sh + 1]
$chBrkBar[sh] = $chBrkBar[sh + 1]
$chBrkPrc[sh] = $chBrkPrc[sh + 1]
NEXT
numCh = maxCh - 1
ENDIF
$chTop[numCh] = chanH
$chBot[numCh] = chanL
$chLeft[numCh] = barindex - dur
$chRight[numCh] = barindex
$chActive[numCh] = 1
$chDir[numCh] = 0
$chBrkBar[numCh] = 0
$chBrkPrc[numCh] = 0
numCh = numCh + 1
ENDIF
ENDIF
//---------------------------------------------------
// ===== DETECCIÓN BREAKOUT =====
//---------------------------------------------------
IF strongClose = 1 THEN
testPrc = (close + open) / 2
ELSE
testPrc = close
ENDIF
IF numCh > 0 THEN
FOR ib = 0 TO numCh - 1 DO
IF $chActive[ib] = 1 THEN
IF testPrc > $chTop[ib] THEN
$chActive[ib] = 0
$chDir[ib] = 1
$chRight[ib] = barindex
$chBrkBar[ib] = barindex
$chBrkPrc[ib] = $chBot[ib]
ELSIF testPrc < $chBot[ib] THEN
$chActive[ib] = 0
$chDir[ib] = -1
$chRight[ib] = barindex
$chBrkBar[ib] = barindex
$chBrkPrc[ib] = $chTop[ib]
ELSE
$chRight[ib] = barindex
ENDIF
ENDIF
NEXT
ENDIF
// ATR para zonas internas
halfATR = averagetruerange[boxLength] / 2
//---------------------------------------------------
// ==== DIBUJO ===
//---------------------------------------------------
IF islastbarupdate AND numCh > 0 THEN
FOR id = 0 TO numCh - 1 DO
// Canal principal (gris)
DRAWRECTANGLE($chLeft[id], $chTop[id], $chRight[id], $chBot[id]) coloured(128, 128, 128, 255) fillcolor(128, 128, 128, 120)
// Zona superior roja
topZBot = $chTop[id] - halfATR
IF topZBot < $chBot[id] THEN
topZBot = ($chTop[id] + $chBot[id]) / 2
ENDIF
DRAWRECTANGLE($chLeft[id], $chTop[id], $chRight[id], topZBot) coloured(255, 50, 0, 255) fillcolor(255, 50, 0, 180)
// Zona inferior verde
botZTop = $chBot[id] + halfATR
IF botZTop > $chTop[id] THEN
botZTop = ($chTop[id] + $chBot[id]) / 2
ENDIF
DRAWRECTANGLE($chLeft[id], botZTop, $chRight[id], $chBot[id]) coloured(0, 200, 100, 255) fillcolor(0, 200, 100, 180)
// Línea central
midY = ($chTop[id] + $chBot[id]) / 2
DRAWSEGMENT($chLeft[id], midY, $chRight[id], midY) coloured(180, 180, 180) style(dottedline, 1)
// Señales de breakout
IF $chDir[id] = 1 AND $chBrkBar[id] > 0 THEN
DRAWARROWUP($chBrkBar[id], $chBrkPrc[id]) coloured(0, 255, 187)
ELSIF $chDir[id] = -1 AND $chBrkBar[id] > 0 THEN
DRAWARROWDOWN($chBrkBar[id], $chBrkPrc[id]) coloured(255, 17, 0)
ENDIF
NEXT
// --- GAUGE ---
IF showGauge = 1 THEN
// Buscar canal activo más reciente
activeIdx = -2
FOR ig = 0 TO numCh - 1 DO
jg = numCh - 1 - ig
IF activeIdx = -2 AND $chActive[jg] = 1 THEN
activeIdx = jg
ENDIF
NEXT
IF activeIdx >= 0 THEN
gTop = $chTop[activeIdx]
gBot = $chBot[activeIdx]
gRange = gTop - gBot
IF gRange > 0 THEN
nSeg = 7
segH = gRange / nSeg
gX1 = barindex + 2
gX2 = barindex + 4
FOR gs = 0 TO nSeg - 1 DO
segTop = gTop - gs * segH
segBot = gTop - (gs + 1) * segH
IF gs = 0 THEN
cr = 0
cg = 220
cb = 120
ELSIF gs = 1 THEN
cr = 50
cg = 200
cb = 80
ELSIF gs = 2 THEN
cr = 120
cg = 180
cb = 40
ELSIF gs = 3 THEN
cr = 200
cg = 200
cb = 0
ELSIF gs = 4 THEN
cr = 220
cg = 140
cb = 0
ELSIF gs = 5 THEN
cr = 240
cg = 80
cb = 0
ELSE
cr = 255
cg = 30
cb = 0
ENDIF
DRAWRECTANGLE(gX1, segTop, gX2, segBot) coloured(cr, cg, cb) fillcolor(cr, cg, cb)
NEXT
// Puntero gauge
IF hvold - lvold <> 0 THEN
normDlt = (volDelta - lvold) / (hvold - lvold)
ELSE
normDlt = 0.5
ENDIF
delvol = -200 * normDlt + 100
IF delvol > 100 THEN
delvol = 100
ENDIF
IF delvol < -100 THEN
delvol = -100
ENDIF
ptrPos = gTop - ((delvol + 100) / 200) * gRange
DRAWTEXT("◀", gX2 + 1, ptrPos) coloured(0, 0, 0)
ENDIF
ENDIF
ENDIF
ENDIF
RETURN
This topic contains 2 replies,
has 2 voices, and was last updated by
Iván González
1 day, 14 hours ago.
| Forum: | TradingView to ProRealTime Translation Center Forum |
| Started: | 02/25/2026 |
| Status: | Active |
| Attachments: | No files |
The information collected on this form is stored in a computer file by ProRealCode to create and access your ProRealCode profile. This data is kept in a secure database for the duration of the member's membership. They will be kept as long as you use our services and will be automatically deleted after 3 years of inactivity. Your personal data is used to create your private profile on ProRealCode. This data is maintained by SAS ProRealCode, 407 rue Freycinet, 59151 Arleux, France. If you subscribe to our newsletters, your email address is provided to our service provider "MailChimp" located in the United States, with whom we have signed a confidentiality agreement. This company is also compliant with the EU/Swiss Privacy Shield, and the GDPR. For any request for correction or deletion concerning your data, you can directly contact the ProRealCode team by email at privacy@prorealcode.com If you would like to lodge a complaint regarding the use of your personal data, you can contact your data protection supervisory authority.