Gaps indicator (similar to TradingView)
Forums › ProRealTime English forum › ProBuilder support › Gaps indicator (similar to TradingView)
- This topic has 6 replies, 4 voices, and was last updated 3 weeks ago by
Iván.
-
-
08/01/2025 at 4:08 PM #249243
Parameters/inputs:
- close gap partially: (boolean, YES or NO)
- minimal deviation: as volatility multiple
nATR := vol = AverageTrueRange[periodATR] / Close
, threshold = x - limit max gap trail length: (boolean)
- if = 1, then length = y
- up gaps and down gaps colors
A gap is a visible empty space between two candles.
Mathematically:Close(t−1) ≠ Open(t)
, wheret
defines the time when the gapping candle occurs.If
|Close(t−1) - Open(t)| ≥ x * Vol(t−1)
then the gap is considered significant.If that empty space gets partially or fully filled between
t
andt+n
, the gap must be updated to reflect the remaining unfilled space on the chart.
Example:
Close(t−1) = 5
Open(t) = 10
Vol(t−1) = 0.1
x = 2
Then:
|5 - 10| = 5
2 * 0.1 * 5 = 1
Since 5 ≥ 1 → gap is significant.If in
t+1
the candle low reaches 8, then the remaining gap is from 5 to 8.
Same applies if, int
, the gapping candle haslow < open
. That portion is considered filled and must be removed.General rule:
0 ≤ unfilled space ≤ |Close(t−1) - Open(t)| := gap
Here is the Pine Script version
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117//@version=6indicator("Gaps", overlay = true, max_boxes_count = 500)closeGapsPartially = input.bool(false, "Close Gaps Partially", display = display.data_window)boxLimitInput = input.int(15, "Max Number of Gaps", minval = 1, maxval = 500, display = display.data_window)minimalDeviationTooltip = "Specifies the minimal size of detected gaps, as a percentage of the average high-low range for the last 14 bars."minimalDeviationInput = nz(input.float(30.0, "Minimal Deviation (%)", tooltip = minimalDeviationTooltip, minval=1, maxval=100, display = display.data_window) / 100 * ta.sma(high-low, 14))limitBoxLengthBoolInput = input.bool(false, "Limit Max Gap Trail Length (bars)", inline = "Length Limit", display = display.data_window)limitBoxLengthIntInput = input.int(300, "", inline = "Length Limit", minval = 1, display = display.data_window)groupName = "Border and fill colors"colorUpBorderInput = input.color(color.green, "Up Gaps", inline = "Gap Up", group = groupName, display = display.data_window)colorUpBackgroundInput = input.color(color.new(color.green, 85), "", inline = "Gap Up", group = groupName, display = display.data_window)colorDownBorderInput = input.color(color.red, "Down Gaps", inline = "Gap Down", group = groupName, display = display.data_window)colorDownBackgroundInput = input.color(color.new(color.red, 85), "", inline = "Gap Down", group = groupName, display = display.data_window)type AlertInfoint countOpenGapint countClosedGapmethod hasOpenedGap(AlertInfo this) =>this.countOpenGap > 0method hasClosedGap(AlertInfo this) =>this.countClosedGap > 0AlertInfo alertInfo = AlertInfo.new(0, 0)type Gapbool isActivebool isBullarray<box> boxesmethod delete(Gap this) =>for _box in this.boxes_box.delete()method partialClose(Gap this) =>activeBox = this.boxes.last()activeBox.set_extend(extend.none)top = this.isBull ? activeBox.get_top() : lowbottom = this.isBull ? high : activeBox.get_bottom()this.boxes.push(box.new(bar_index,top,bar_index,bottom,this.isBull ? colorDownBorderInput : colorUpBorderInput,bgcolor = this.isBull ? colorDownBackgroundInput : colorUpBackgroundInput))method fullClose(Gap this) =>alertInfo.countClosedGap += 1activeBox = this.boxes.last()activeBox.set_extend(extend.none)this.isActive := falseif closeGapsPartiallyactiveBox.delete()method checkForClose(Gap this) =>if this.isActiveactiveBox = this.boxes.last()top = activeBox.get_top()bot = activeBox.get_bottom()isBull = this.isBullactiveBox.set_right(bar_index)if (high > bot and isBull) or (low < top and not isBull)if closeGapsPartiallythis.partialClose()elsethis.fullClose()bool forceCloseBoxExceededLengthLimit = (limitBoxLengthBoolInput and bar_index - activeBox.get_left() >= limitBoxLengthIntInput)if ((high > top and isBull) or (low < bot and not isBull)) or forceCloseBoxExceededLengthLimitthis.fullClose()var allGaps = array.new<Gap>()isGapDown = high < low[1] and low[1] - high >= minimalDeviationInputisGapUp = low > high[1] and low - high[1] >= minimalDeviationInputisGap = isGapDown or isGapUpboxBorderColor = isGapDown ? colorDownBorderInput : colorUpBorderInputboxBgcolor = isGapDown ? colorDownBackgroundInput : colorUpBackgroundInputregisterNewGap(bool isGapDown) =>alertInfo.countOpenGap += 1newBox = box.new(bar_index - 1,(isGapDown ? low[1] : low),bar_index,(isGapDown ? high : high[1]),border_color = boxBorderColor,bgcolor = boxBgcolor,extend = extend.right)allGaps.push(Gap.new(true, isGapDown, array.from(newBox)))if allGaps.size() > boxLimitInputallGaps.shift().delete()for gap in allGapsgap.checkForClose()if isGapregisterNewGap(isGapDown)if barstate.islastconfirmedhistory and allGaps.size() == 0noGapText = "No gaps found on the current chart. \nThe cause could be that some exchanges align the open of new bars on the close of the previous one, resulting in charts with no gaps. Alternatively, your Minimal Deviation might be too high."var infoTable = table.new(position.bottom_right, 1, 1)table.cell(infoTable, 0, 0, text = noGapText, text_color = chart.bg_color, bgcolor = chart.fg_color)alertcondition(alertInfo.hasOpenedGap(), "New Gap Appeared", "A new gap has appeared.")alertcondition(alertInfo.hasClosedGap(), "Gap Closed", "A gap was closed.")
Note: The version we want is slightly different — it detects gaps using
Close(t−1)
instead ofHigh(t−1)
which is more accurate.08/03/2025 at 10:59 AM #24930108/03/2025 at 12:22 PM #249302Anyone knows how to code it?
08/03/2025 at 1:00 PM #24930308/03/2025 at 5:54 PM #249316This is a completely different indicator…
There is currently no alternative to the one from TradingView on this forum
08/03/2025 at 6:42 PM #24931708/20/2025 at 3:22 PM #249925you can start with this:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129// --- PARÁMETROS CONFIGURABLES ---closeGapsPartially = 1minimalDeviationPercent = 30// --- INICIALIZACIÓN ---ONCE gapCount = 0ONCE rectCount = 0// --- BLOQUE 1: CÁLCULO Y GESTIÓN DE ESTADO (Se ejecuta en cada recálculo de cada barra) ---// Resetear contadores en la primera barra del gráficoIF BarIndex = 0 THENgapCount = 0rectCount = 0ENDIF// Calcular desviación mínimarangeSMA = Average[14](high-low)minimalDeviation = (minimalDeviationPercent / 100) * rangeSMA// --- Detección de nuevos gaps ---isGapUp = low > high[1] AND low - high[1] >= minimalDeviationisGapDown = high < low[1] AND low[1] - high >= minimalDeviationIF isGapUp OR isGapDown THENn=gapCount$gapIsActive[n] = 2// 2=Inicial;1=Parcial;0=Cerrado$gapStartIndex[n] = BarIndex-1$gapEndIndex[n] = BarIndexIF isGapUp THEN$gapTop[n] = low$gapBottom[n] = high[1]$gapType[n]=1ELSE // isGapDown$gapTop[n] = low[1]$gapBottom[n] = high$gapType[n]=-1ENDIFgapCount = gapCount + 1ENDIF// --- Gestión de cierres de gaps activos ---FOR i = 0 TO gapCount - 1 DOIF $gapIsActive[i] = 2 THEN// Cierre COMPLETOIF ($gapType[i]>0 AND low < $gapBottom[i]) OR ($gapType[i]<0 AND high > $gapTop[i]) THEN// Guardar el rectángulo final en la memoria$rectX1[rectCount] = $gapStartIndex[i]//-1$rectY1[rectCount] = $gapTop[i]$rectX2[rectCount] = BarIndex$rectY2[rectCount] = $gapBottom[i]$rectType[rectCount] = $gapType[i]$rectGAP[rectCount] = irectCount = rectCount + 1$gapIsActive[i] = 0 // Desactivar el gap// Cierre PARCIAL (solo si la opción está activa)ELSIF closeGapsPartially = 1 AND (($gapType[i]>0 AND low < $gapTop[i]) OR ($gapType[i]<0 AND high > $gapBottom[i])) THEN$gapIsActive[i] = 1 // Guardar el rectángulo de la parte rellenada en la memoria$rectX1[rectCount] = $gapStartIndex[i] //- 1$rectX2[rectCount] = BarIndexif $gapType[i]>0 then$rectY1[rectCount] = $gapBottom[i]$rectY2[rectCount] = $gapTop[i]// IIF(cond, true, false)else$rectY1[rectCount] = $gapTop[i]$rectY2[rectCount] = $gapBottom[i]endif$rectType[rectCount] = $gapType[i]$rectGAP[rectCount] = irectCount = rectCount + 1// Actualizar el gap activo con las nuevas coordenadas$gapStartIndex[i] = BarIndexIF $gapType[i]>0 THEN$gapTop[i] = lowELSE$gapBottom[i] = highENDIFENDIFelsif $gapIsActive[i] = 1 then// Cierre COMPLETOIF ($gapType[i]>0 AND low < $gapBottom[i]) OR ($gapType[i]<0 AND high > $gapTop[i]) THEN// Guardar el rectángulo final en la memoria$rectX1[rectCount] = $gapStartIndex[i]//-1$rectY1[rectCount] = $gapTop[i]$rectX2[rectCount] = BarIndex$rectY2[rectCount] = $gapBottom[i]$rectType[rectCount] = $gapType[i]$rectGAP[rectCount] = irectCount = rectCount + 1$gapIsActive[i] = 0 // Desactivar el gap// Cierre PARCIAL (solo si la opción está activa)ELSIF closeGapsPartially = 1 AND (($gapType[i]>0 AND low < $gapTop[i]) OR ($gapType[i]<0 AND high > $gapBottom[i])) THEN // Guardar el rectángulo de la parte rellenada en la memoria$rectX1[rectCount] = $gapStartIndex[i] //- 1$rectX2[rectCount] = BarIndexif $gapType[i]>0 then$rectY1[rectCount] = $gapBottom[i]$rectY2[rectCount] = $gapTop[i] // IIF(cond, true, false)else$rectY1[rectCount] = $gapTop[i]$rectY2[rectCount] = $gapBottom[i]endif$rectType[rectCount] = $gapType[i]$rectGAP[rectCount] = irectCount = rectCount + 1// Actualizar el gap activo con las nuevas coordenadas$gapStartIndex[i] = BarIndexIF $gapType[i]>0 THEN$gapTop[i] = lowELSE$gapBottom[i] = highENDIFendifENDIFNEXTIF islastbarupdate THEN// Dibujar todos los rectángulos históricos memorizadosFOR r = 0 TO rectCount - 1 DOIF $rectType[r] = 1 THENDRAWRECTANGLE($rectX1[r], $rectY1[r], $rectX2[r], $rectY2[r]) coloured("green")fillcolor("green",30)ELSEDRAWRECTANGLE($rectX1[r], $rectY1[r], $rectX2[r], $rectY2[r]) coloured("red")fillcolor("red",30)ENDIFNEXT// Dibujar todos los gaps que siguen activosFOR i = 0 TO gapCount - 1 DOIF $gapIsActive[i] > 0 THENstartIndex = $gapStartIndex[i] //- 1gapTop = $gapTop[i]endIndex = BarIndexgapBottom = $gapBottom[i]IF $gapType[i]>0 THENDRAWRECTANGLE(startIndex, gapTop, endIndex, gapBottom) coloured("green")fillcolor("green",30)ELSEDRAWRECTANGLE(startIndex, gapTop, endIndex, gapBottom)coloured("red")fillcolor("red",30)ENDIFENDIFNEXTENDIFRETURN -
AuthorPosts
Find exclusive trading pro-tools on