Indicator · Pine Script v6 · On the chart

Range Indicator: Golden Pocket, Liquidity, & FVG

by Corbanistan

This indicator draws a trading range box on the price chart, based on a rolling lookback, the previous day or the previous week.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code281
Settings25inputs
LicenceMPL-2.0
Last update9 months ago27 Jan 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

281 lines of Pine Script v6 from range_indicator_golden_pocket.pine, published under MPL-2.0. Keep the author's credit and licence lines when you reuse it.

range_indicator_golden_pocket.pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Corbanistan

//@version=6
indicator('Range Indicator: Golden Pocket, Liquidity, & FVG', overlay = true, max_lines_count = 500, max_boxes_count = 500)

// ══════════════════════════════════════════════════════════════════════════════
// 1. INPUT SETTINGS
// ══════════════════════════════════════════════════════════════════════════════

// --- Visual Settings ---
string GRP_VIS = 'Visuals'
color i_boxColor       = input.color(color.new(#787b86, 92), 'Range Background', group = GRP_VIS)
color i_gpBullishColor = input.color(color.new(#4caf50, 60), 'Bullish GP Color', group = GRP_VIS)
color i_gpBearishColor = input.color(color.new(#f44336, 60), 'Bearish GP Color', group = GRP_VIS)
color i_liqColor       = input.color(color.new(#ffeb3b, 85), 'Liquidity Zones Color', group = GRP_VIS)
color i_lineColor      = input.color(color.white, 'Boundary Line Color', group = GRP_VIS)
bool  i_showLines      = input.bool(true, 'Show Price Lines', group = GRP_VIS)
bool  i_showLabels     = input.bool(true, 'Show Price Labels', group = GRP_VIS)
bool  i_showSignals    = input.bool(true, 'Show Signal Markers', group = GRP_VIS, tooltip = 'Display chart markers for trading signals: ▲ Long (bullish GP + 2-candle reversal), ▼ Short (bearish GP + 2-candle reversal), ● SFP (liquidity grab at range extremes).')

// --- Range Settings ---
string GRP_RANGE = 'Range Settings'
string MODE_ROLLING = 'Rolling Lookback'
string MODE_PREV_DAY = 'Previous Day'
string MODE_PREV_WEEK = 'Previous Week'
string i_rangeMode     = input.string(MODE_ROLLING, 'Range Mode', options = [MODE_ROLLING, MODE_PREV_DAY, MODE_PREV_WEEK], group = GRP_RANGE)
bool   i_autoFit       = input.bool(true, 'Auto-Fit Box to Last High/Low (Rolling Only)', group = GRP_RANGE)
int    i_lookback      = input.int(100, 'Lookback Period (Rolling Only)', minval = 2, group = GRP_RANGE)
int    i_offsetR       = input.int(50, 'Box Offset Right', minval = 0, group = GRP_RANGE)

// --- FVG Settings ---
string GRP_FVG = 'FVG Settings'
bool   i_showFVG       = input.bool(true, 'Show Fair Value Gaps (FVG)', group = GRP_FVG)
int    i_fvgLen        = input.int(10, 'FVG Extension (Bars)', minval = 1, group = GRP_FVG)
color  i_bullFVGColor  = input.color(color.new(#4caf50, 50), 'Bullish FVG Color', group = GRP_FVG)
color  i_bearFVGColor  = input.color(color.new(#f44336, 50), 'Bearish FVG Color', group = GRP_FVG)

// --- Moving Average Settings ---
string GRP_MA = 'Moving Average'
bool   i_showMA        = input.bool(false, 'Show Moving Average', group = GRP_MA)
string MA_SMA  = 'SMA'
string MA_EMA  = 'EMA'
string MA_WMA  = 'WMA'
string MA_VWMA = 'VWMA'
string MA_RMA  = 'RMA'
string MA_HMA  = 'HMA'
string MA_SMMA = 'SMMA'
string MA_DEMA = 'DEMA'
string MA_TEMA = 'TEMA'
string i_maType        = input.string(MA_SMA, 'MA Type', options = [MA_SMA, MA_EMA, MA_WMA, MA_VWMA, MA_RMA, MA_HMA, MA_SMMA, MA_DEMA, MA_TEMA], group = GRP_MA)
int    i_maLen         = input.int(20, 'MA Length', minval = 1, group = GRP_MA)
string i_maSrc         = input.string('close', 'MA Source', options = ['open', 'high', 'low', 'close', 'hl2', 'hlc3', 'ohlc4', 'hlcc4'], group = GRP_MA)
bool   i_maSmooth      = input.bool(false, 'Apply Smoothing', group = GRP_MA)
int    i_maSmoothLen   = input.int(3, 'Smoothing Length', minval = 1, group = GRP_MA)
string i_maSmoothType  = input.string(MA_SMA, 'Smoothing Type', options = [MA_SMA, MA_EMA, MA_WMA, MA_RMA], group = GRP_MA)
color  i_maColor       = input.color(color.new(#2196f3, 0), 'MA Color', group = GRP_MA)
int    i_maWidth       = input.int(2, 'MA Line Width', minval = 1, maxval = 5, group = GRP_MA)

// ══════════════════════════════════════════════════════════════════════════════
// 2. CORE RANGE CALCULATIONS
// ══════════════════════════════════════════════════════════════════════════════

// Calculate range high/low based on selected mode
// Fix: Use [1] offset to exclude current bar from range calculation (enables proper SFP detection)
var float rHigh = na
var float rLow = na
var int anchorBar = na

if i_rangeMode == MODE_ROLLING
    // Rolling lookback mode - exclude current bar for proper SFP signals
    if bar_index < i_lookback + 1
        // Insufficient history: use all available bars
        rHigh := ta.highest(high, bar_index + 1)
        rLow := ta.lowest(low, bar_index + 1)
        anchorBar := 0
    else
        // Note: highestbars/lowestbars return negative offsets, use math.abs for indexing
        int hOff = ta.highestbars(high[1], i_lookback)
        int lOff = ta.lowestbars(low[1], i_lookback)
        rHigh := high[1 + math.abs(hOff)]
        rLow := low[1 + math.abs(lOff)]
        anchorBar := i_autoFit ? bar_index - math.max(math.abs(hOff), math.abs(lOff)) - 1 : bar_index - i_lookback
else if i_rangeMode == MODE_PREV_DAY
    // Previous day high/low - stable non-repainting levels
    rHigh := request.security(syminfo.tickerid, 'D', high[1], lookahead = barmerge.lookahead_on)
    rLow := request.security(syminfo.tickerid, 'D', low[1], lookahead = barmerge.lookahead_on)
    anchorBar := bar_index - i_lookback  // Approximate anchor
else if i_rangeMode == MODE_PREV_WEEK
    // Previous week high/low - stable non-repainting levels
    rHigh := request.security(syminfo.tickerid, 'W', high[1], lookahead = barmerge.lookahead_on)
    rLow := request.security(syminfo.tickerid, 'W', low[1], lookahead = barmerge.lookahead_on)
    anchorBar := bar_index - i_lookback  // Approximate anchor

float rDiff = rHigh - rLow

// Golden Pocket Fibonacci levels
float bUp = rLow + rDiff * 0.382   // Bullish GP upper
float bLo = rLow + rDiff * 0.35    // Bullish GP lower
float sUp = rHigh - rDiff * 0.35   // Bearish GP upper
float sLo = rHigh - rDiff * 0.382  // Bearish GP lower

// ══════════════════════════════════════════════════════════════════════════════
// 3. FVG LOGIC (Simple Static Boxes)
// ══════════════════════════════════════════════════════════════════════════════

if i_showFVG
    // Bullish FVG: gap up (current low > 2 bars ago high)
    if low > high[2]
        box.new(bar_index[1], low, bar_index + i_fvgLen, high[2], bgcolor = i_bullFVGColor, border_color = na)
    // Bearish FVG: gap down (current high < 2 bars ago low)
    if high < low[2]
        box.new(bar_index[1], high, bar_index + i_fvgLen, low[2], bgcolor = i_bearFVGColor, border_color = na)


// ══════════════════════════════════════════════════════════════════════════════
// 4. MOVING AVERAGE CALCULATIONS
// ══════════════════════════════════════════════════════════════════════════════

// Get the price source for MA calculation
float maSrc = switch i_maSrc
    'open'  => open
    'high'  => high
    'low'   => low
    'close' => close
    'hl2'   => hl2
    'hlc3'  => hlc3
    'ohlc4' => ohlc4
    'hlcc4' => hlcc4
    => close

// Pre-calculate ALL MA types on every bar to ensure consistent TA function calls
// (Pine Script requires TA functions to be called on each bar for accurate historical state)
float ma_sma  = ta.sma(maSrc, i_maLen)
float ma_ema  = ta.ema(maSrc, i_maLen)
float ma_wma  = ta.wma(maSrc, i_maLen)
float ma_vwma = nz(volume) > 0 ? ta.vwma(maSrc, i_maLen) : ma_sma  // Fallback to SMA on no-volume symbols
float ma_rma  = ta.rma(maSrc, i_maLen)
float ma_hma  = ta.hma(maSrc, i_maLen)
// DEMA = 2 * EMA - EMA(EMA) (reuse ma_ema for efficiency)
float dema_ema2 = ta.ema(ma_ema, i_maLen)
float ma_dema   = 2 * ma_ema - dema_ema2
// TEMA = 3 * EMA - 3 * EMA(EMA) + EMA(EMA(EMA)) (reuse previous EMAs)
float tema_ema3 = ta.ema(dema_ema2, i_maLen)
float ma_tema   = 3 * ma_ema - 3 * dema_ema2 + tema_ema3

// Select the appropriate pre-calculated MA based on user choice
float maValue = switch i_maType
    MA_SMA  => ma_sma
    MA_EMA  => ma_ema
    MA_WMA  => ma_wma
    MA_VWMA => ma_vwma
    MA_RMA  => ma_rma
    MA_HMA  => ma_hma
    MA_SMMA => ma_rma  // SMMA is equivalent to RMA
    MA_DEMA => ma_dema
    MA_TEMA => ma_tema
    => ma_sma

// Pre-calculate smoothing MAs (all types, called every bar)
float smooth_sma = ta.sma(maValue, i_maSmoothLen)
float smooth_ema = ta.ema(maValue, i_maSmoothLen)
float smooth_wma = ta.wma(maValue, i_maSmoothLen)
float smooth_rma = ta.rma(maValue, i_maSmoothLen)

// Select smoothed value if smoothing is enabled
float maSmoothed = switch i_maSmoothType
    MA_SMA => smooth_sma
    MA_EMA => smooth_ema
    MA_WMA => smooth_wma
    MA_RMA => smooth_rma
    => smooth_sma

float maFinal = i_maSmooth ? maSmoothed : maValue

// Plot the moving average (conditional on toggle)
plot(i_showMA ? maFinal : na, 'Moving Average', color = i_maColor, linewidth = i_maWidth)

// ══════════════════════════════════════════════════════════════════════════════
// 5. VISUAL ELEMENTS (Boxes, Lines, Labels)
// ══════════════════════════════════════════════════════════════════════════════

var box b_Range   = box.new(na, na, na, na, xloc = xloc.bar_index, bgcolor = i_boxColor, border_color = color.gray)
var box b_Bullish = box.new(na, na, na, na, xloc = xloc.bar_index, bgcolor = i_gpBullishColor, border_color = na, text = 'BULLISH Golden Pocket ↑', text_color = color.white, text_size = size.small)
var box b_Bearish = box.new(na, na, na, na, xloc = xloc.bar_index, bgcolor = i_gpBearishColor, border_color = na, text = 'BEARISH Golden Pocket ↓', text_color = color.white, text_size = size.small)
var box b_LiqTop  = box.new(na, na, na, na, xloc = xloc.bar_index, bgcolor = i_liqColor, border_color = na, text = 'LIQUIDITY', text_color = color.white, text_size = size.tiny)
var box b_LiqBot  = box.new(na, na, na, na, xloc = xloc.bar_index, bgcolor = i_liqColor, border_color = na, text = 'LIQUIDITY', text_color = color.white, text_size = size.tiny)

var array<line>  l_levels  = array.new<line>()
var array<label> lb_prices = array.new<label>()

if barstate.isfirst
    for i = 0 to 7
        array.push(l_levels, line.new(na, na, na, na, xloc = xloc.bar_index, color = i_lineColor))
        array.push(lb_prices, label.new(na, na, '', xloc = xloc.bar_index, color = color.new(color.black, 100), textcolor = i_lineColor, size = size.small, style = label.style_label_left))

if barstate.islast
    int rightBar = bar_index + i_offsetR
    
    // Update main boxes
    box.set_lefttop(b_Range, anchorBar, rHigh)
    box.set_rightbottom(b_Range, rightBar, rLow)
    box.set_lefttop(b_Bullish, anchorBar, bUp)
    box.set_rightbottom(b_Bullish, rightBar, bLo)
    box.set_lefttop(b_Bearish, anchorBar, sUp)
    box.set_rightbottom(b_Bearish, rightBar, sLo)
    box.set_lefttop(b_LiqTop, anchorBar, rHigh)
    box.set_rightbottom(b_LiqTop, rightBar, rHigh - rDiff * 0.05)
    box.set_lefttop(b_LiqBot, anchorBar, rLow + rDiff * 0.05)
    box.set_rightbottom(b_LiqBot, rightBar, rLow)
    
    // Update price lines and labels
    array<float> p_vals = array.from(rHigh, rHigh - rDiff * 0.05, sUp, sLo, bUp, bLo, rLow + rDiff * 0.05, rLow)
    for i = 0 to 7
        float v = array.get(p_vals, i)
        // Update lines if enabled
        if i_showLines
            line.set_xy1(array.get(l_levels, i), anchorBar, v)
            line.set_xy2(array.get(l_levels, i), rightBar, v)
        else
            line.set_xy1(array.get(l_levels, i), na, na)
            line.set_xy2(array.get(l_levels, i), na, na)
        // Update labels if enabled
        if i_showLabels
            label.set_xy(array.get(lb_prices, i), rightBar, v)
            label.set_text(array.get(lb_prices, i), ' ' + str.tostring(v, format.mintick))
        else
            label.set_xy(array.get(lb_prices, i), na, na)

// ══════════════════════════════════════════════════════════════════════════════
// 6. SIGNAL LOGIC
// ══════════════════════════════════════════════════════════════════════════════

// Swing Failure Pattern (SFP) - now works correctly with [1] offset fix
bool sfpShort = high > rHigh and close < rHigh
bool sfpLong  = low < rLow and close > rLow

// Golden Pocket touch tracking
var bool tBear = false
var bool tBull = false

if high >= sLo and low <= sUp
    tBear := true

if low <= bUp and high >= bLo
    tBull := true

// 2-Candle reversal pattern
bool pL = close[2] < open[2] and close[1] > open[1] and close > high[1]  // Bullish reversal
bool pS = close[2] > open[2] and close[1] < open[1] and close < low[1]   // Bearish reversal

// Combined signals
bool signalLongOnly  = tBull and pL
bool signalShortOnly = tBear and pS

// Reset touch flags after signal or breakout
if signalShortOnly or (tBear and high > rHigh)
    tBear := false

if signalLongOnly or (tBull and low < rLow)
    tBull := false

// Signal visualization (optional markers on chart)
plotshape(i_showSignals and signalLongOnly, 'Long Signal', shape.triangleup, location.belowbar, color.new(#4caf50, 0), size = size.small)
plotshape(i_showSignals and signalShortOnly, 'Short Signal', shape.triangledown, location.abovebar, color.new(#f44336, 0), size = size.small)
plotshape(i_showSignals and sfpLong, 'SFP Long', shape.circle, location.belowbar, color.new(#ff9800, 0), size = size.tiny)
plotshape(i_showSignals and sfpShort, 'SFP Short', shape.circle, location.abovebar, color.new(#ff9800, 0), size = size.tiny)

// ══════════════════════════════════════════════════════════════════════════════
// 7. ALERTS
// ══════════════════════════════════════════════════════════════════════════════

// GP touch detection - handles both crossovers and gap opens into the zone
bool gpTouchBearish = high >= sLo and high[1] < sLo
bool gpTouchBullish = low <= bUp and low[1] > bUp

alertcondition(gpTouchBearish or gpTouchBullish, '1. GP Touch', 'Price entered Golden Pocket zone.')
alertcondition(signalLongOnly, '2. Long: 2-Candle Pattern', 'Long signal confirmed in BULLISH Golden Pocket.')
alertcondition(signalShortOnly, '3. Short: 2-Candle Pattern', 'Short signal confirmed in BEARISH Golden Pocket.')
alertcondition(sfpLong, '4. SFP Long (Liquidity Grab)', 'SFP detected: Liquidity grab below range low.')
alertcondition(sfpShort, '5. SFP Short (Liquidity Grab)', 'SFP detected: Liquidity grab above range high.')

Overview

Inside it, it marks golden pocket Fibonacci zones, liquidity areas near the range extremes and fair value gaps that extend a set number of bars. Optional signal markers show long and short reversal setups and swing failure patterns. A configurable moving average with nine types and optional smoothing can be added.

Details

Published by

Corbanistan on GitHub

Type

Indicator, Pine Script v6

Draws

On the price chart

Category

SMC / ICT / price action, Support & resistance

Markets

Any symbol

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
Range Backgroundcolorcolor.new(#787b86, 92)i_boxColor
Bullish GP Colorcolorcolor.new(#4caf50, 60)i_gpBullishColor
Bearish GP Colorcolorcolor.new(#f44336, 60)i_gpBearishColor
Liquidity Zones Colorcolorcolor.new(#ffeb3b, 85)i_liqColor
Boundary Line Colorcolorcolor.whitei_lineColor
Show Price Linesbooltruei_showLines
Show Price Labelsbooltruei_showLabels
Show Signal Markersbooltruei_showSignals
Range ModestringMODE_ROLLINGi_rangeMode
Auto-Fit Box to Last High/Low (Rolling Only)booltruei_autoFit
Lookback Period (Rolling Only)int100i_lookback
Box Offset Rightint50i_offsetR
Show all 25 settings
SettingTypeDefaultVariable
Show Fair Value Gaps (FVG)booltruei_showFVG
FVG Extension (Bars)int10i_fvgLen
Bullish FVG Colorcolorcolor.new(#4caf50, 50)i_bullFVGColor
Bearish FVG Colorcolorcolor.new(#f44336, 50)i_bearFVGColor
Show Moving Averageboolfalsei_showMA
MA TypestringMA_SMAi_maType
MA Lengthint20i_maLen
MA Sourcestringclosei_maSrc
Apply Smoothingboolfalsei_maSmooth
Smoothing Lengthint3i_maSmoothLen
Smoothing TypestringMA_SMAi_maSmoothType
MA Colorcolorcolor.new(#2196f3, 0)i_maColor
MA Line Widthint2i_maWidth
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

ICT Equal Highs and Lows

by ArunKBhaskar
575 stars

This overlay indicator finds pivot highs and lows on the price chart and compares the last two highs and the last two lows. When the percentage difference between a pair is below the Equal HL threshold, it treats them as equal levels and draws a box. Left and

Indicator v5 SMC / ICT / price actionSupport & resistance
Updated 1 year ago · MPL-2.0 GitHub repository of ICT Equal Highs and Lows

DE-tracker

by Allen1212
303 stars

This indicator plots labels on the TradingView price chart to mark ARK Invest's buy and sell trades for the DE stock. Buy transactions appear in green with X1 or X2 multipliers showing the number of ARK ETFs involved on the same day; sells appear in red. The m

Indicator v4 Support & resistanceSMC / ICT / price action
Updated 2 years ago · None stated GitHub repository of DE-tracker

This Pine Script indicator plots a ZigZag on the price chart. It identifies reversal points when price moves more than a set percentage from the last pivot. The script calculates forecasts using zigzag data and labels detected geometric patterns including harm

Indicator v4 TrendSupport & resistance

Golden Bullet Strategy

by TradersPost
218 stars

The Golden Bullet Strategy is an overlay signal indicator based on Smart Money Concepts and time-based liquidity models. It identifies liquidity sweeps of a designated reference session range during a specified hunt window. It then confirms Market Structure Sh

Indicator v6 SMC / ICT / price actionSessions & time
Updated 3 months ago · None stated GitHub repository of Golden Bullet Strategy

Open Source Fractal

by cantolab
183 stars

This indicator implements the Fractal Model concept to plot market structure shifts, liquidity sweeps, and Change in State of Delivery (CISD) levels. It overlays custom higher-timeframe candle previews, open prices, and time markers directly on the price chart

Indicator v6 SMC / ICT / price actionSupport & resistance
Updated 2 months ago · MIT GitHub repository of Open Source Fractal

Swing Failure Signals

by Ganador1
154 stars

This indicator calculates pivot highs and pivot lows to detect liquidity sweeps and Swing Failure Patterns. It identifies when price breaks past recent key swing highs or lows within a configurable historical window, then looks for a quick reversal or change i

Indicator v6 SMC / ICT / price actionSupport & resistance
Updated 2 months ago · Apache-2.0 GitHub repository of Swing Failure Signals

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