Indicator · Pine Script v6 · On the chart

Structure Retest Engine Delta Hybrid

by Focal-QuantAI

An indicator on the price chart that detects pivot-based structure breaks (CHoCH) and then looks for a retest of the broken level, using an ATR percentage tolerance.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code324
Settings34inputs
LicenceNone statedfile: MPL-2.0
Last update6 months ago11 Apr 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

324 lines of Pine Script v6 from strategies/structure_retest_engine_delta_hybrid/ymrrHsan1PjWAM_cv2xM_code.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

ymrrHsan1PjWAM_cv2xM_code.pine
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0.
//@version=6
indicator("Structure Retest Engine Delta Hybrid", shorttitle = "SRE-DH", overlay = true, max_labels_count = 500, max_lines_count = 500, max_boxes_count = 500)

// ┌───────────────────────────── Inputs ─────────────────────────────┐
// └──────────────────────────────────────────────────────────────────┘

BULL_COLOR = #089981
BEAR_COLOR = #f23645

GRP_MODEL   = "Model Settings"
GRP_DELTA   = "Delta Analysis"
GRP_FILTERS = "Retest Filters"
GRP_VISUALS = "Visuals"
GRP_ALERTS  = "Alerts"

pivotLen     = input.int(5, "Pivot Length", minval = 1, group = GRP_MODEL, tooltip = "Bars required on each side to confirm a swing point.")
sensitivity  = input.float(0.5, "Retest Sensitivity (ATR %)", minval = 0.05, step = 0.05, group = GRP_MODEL, tooltip = "Defines how close price must come to the level to trigger a retest. Lower values require a more precise touch.")
latestOnly   = input.bool(true, "Show Latest Only", group = GRP_MODEL, tooltip = "Deletes previous structure drawings when a new one forms.")
allowReEntry = input.bool(false, "Allow Re-Entries In Same Zone", group = GRP_MODEL, tooltip = "If disabled, a level is consumed after the first valid entry.")

useDeltaAnalysis = input.bool(true, "Enable Delta Analysis", group = GRP_DELTA, tooltip = "Uses a relative volume delta proxy to judge breakout conviction and retest sentiment.")
deltaMaLen       = input.int(20, "Delta MA Period", minval = 1, group = GRP_DELTA)
deltaThresh      = input.float(1.5, "Run Away Threshold (xMA)", minval = 0.1, step = 0.1, group = GRP_DELTA, tooltip = "Above this threshold, breakout delta is treated as high conviction.")
showDeltaText    = input.bool(true, "Show Delta Insight In Entry Text", group = GRP_DELTA)
showDeltaOnCH    = input.bool(true, "Show Strong/Weak On CHoCH Label", group = GRP_DELTA)

confirmMode  = input.string("Engulfing", "Confirmation Mode", options = ["Touch", "Close Outside Level", "Engulfing"], group = GRP_FILTERS, tooltip = "Touch = immediate reaction. Close Outside Level = candle returns to level then closes back on the trend side. Engulfing = reversal candle confirmation.")
volMaLen     = input.int(20, "Volume MA Length", minval = 1, group = GRP_FILTERS, tooltip = "Period for the Volume Moving Average filter.")
volThresh    = input.float(1.30, "Volume Threshold", minval = 0.1, step = 0.1, group = GRP_FILTERS, tooltip = "Required volume relative to its MA to confirm a retest.")
requireVol   = input.bool(false, "Require Volume Filter", group = GRP_FILTERS, tooltip = "If enabled, confirmation also requires volume above the selected threshold.")
requireCandle = input.bool(false, "Require Directional Candle", group = GRP_FILTERS, tooltip = "Bullish entries require a green candle; bearish entries require a red candle.")

bullCol            = input.color(BULL_COLOR, "Bullish", inline = "col", group = GRP_VISUALS)
bearCol            = input.color(BEAR_COLOR, "Bearish", inline = "col", group = GRP_VISUALS)
showStructureLabel = input.bool(true, "Show CHoCH Labels", group = GRP_VISUALS)
compactLabels      = input.bool(true, "Compact Labels", group = GRP_VISUALS, tooltip = "Uses CH instead of CHoCH for cleaner charts.")
showEntryLabels    = input.bool(true, "Show Entry Text", group = GRP_VISUALS)
colorBarsByTrend   = input.bool(true, "Color Bars By Trend", group = GRP_VISUALS)
fadeUsedZone       = input.bool(true, "Fade Used Levels", group = GRP_VISUALS, tooltip = "Increases transparency of levels once an entry is triggered.")
zoneTransparency   = input.int(85, "Active Transparency", minval = 0, maxval = 100, group = GRP_VISUALS)
usedTransparency   = input.int(95, "Used Transparency", minval = 0, maxval = 100, group = GRP_VISUALS)
entrySizeOpt       = input.string("Tiny", "Entry Triangle Size", options = ["Tiny", "Small", "Normal"], group = GRP_VISUALS)
showBreakLevelLine = input.bool(true, "Show Break Level Line", group = GRP_VISUALS)
showChochTriangle  = input.bool(true, "Show CHoCH Triangle", group = GRP_VISUALS)
chochTriSizeOpt    = input.string("Tiny", "CHoCH Triangle Size", options = ["Tiny", "Small", "Normal"], group = GRP_VISUALS)
showEntryTriangle  = input.bool(true, "Show Entry Triangle", group = GRP_VISUALS)
entryTextOffsetAtr = input.float(0.60, "Entry Text Offset (ATR)", minval = 0.10, step = 0.05, group = GRP_VISUALS, tooltip = "Moves entry text farther away from the candle so it stays readable.")
entryTextSizeOpt   = input.string("Tiny", "Entry Text Size", options = ["Tiny", "Small", "Normal"], group = GRP_VISUALS)
chochTextSizeOpt   = input.string("Small", "CHoCH Text Size", options = ["Tiny", "Small", "Normal"], group = GRP_VISUALS)

alertsOnCHoCH     = input.bool(true, "Include CHoCH In Alert", group = GRP_ALERTS)
alertsOnBullEntry = input.bool(true, "Include Bull Entry In Alert", group = GRP_ALERTS)
alertsOnBearEntry = input.bool(true, "Include Bear Entry In Alert", group = GRP_ALERTS)

// ┌───────────────────────────── Helpers ────────────────────────────┐
// └──────────────────────────────────────────────────────────────────┘

f_entryText(_mode) =>
    _mode == "Touch" ? "TOUCH" : _mode == "Close Outside Level" ? "COL" : "ENG"

// Relative volume delta proxy. This is a candle/volume efficiency estimate, not true bid/ask delta.
f_getDelta() =>
    float _range = high - low
    _range == 0 ? 0.0 : ((close - open) / _range) * volume

f_deltaTag(_breakStrong, _supportsTrend) =>
    _breakStrong and _supportsTrend ? " ⚡" : not _breakStrong and not _supportsTrend ? " ?" : " ~"

f_labelSize(_size) =>
    _size == "Tiny" ? size.tiny : _size == "Small" ? size.small : size.normal

// ┌───────────────────────────── Delta ──────────────────────────────┐
// └──────────────────────────────────────────────────────────────────┘

float candleDelta = f_getDelta()
float absDelta    = math.abs(candleDelta)
float deltaMa     = ta.sma(absDelta, deltaMaLen)

// ┌───────────────────────────── State ──────────────────────────────┐
// └──────────────────────────────────────────────────────────────────┘

var float lastPH      = na
var float lastPL      = na
var int   lastPHIndex = na
var int   lastPLIndex = na
var int   trendState  = 0

var line  activeLevelLine = na
var line  activeBreakLine = na
var box   activeRetestBox = na
var label activeStructLbl = na

var float activeLevel     = na
var int   activeDir       = 0
var int   activeStartIdx  = na
var bool  levelConsumed   = false
var bool  hasLeftLevel    = false
var int   lastCHoCHBar    = -1

var bool wasInBandPrev           = false
var bool entryTriggeredThisTouch = false
var int  retestCount             = 0

var float breakoutDelta  = 0.0
var bool  breakoutStrong = false
var float retestCvd      = 0.0

// ┌───────────────────────────── Pivot Detection ───────────────────┐
// └─────────────────────────────────────────────────────────────────┘

float ph = ta.pivothigh(high, pivotLen, pivotLen)
float pl = ta.pivotlow(low, pivotLen, pivotLen)

if not na(ph)
    lastPH := ph
    lastPHIndex := bar_index - pivotLen

if not na(pl)
    lastPL := pl
    lastPLIndex := bar_index - pivotLen

// ┌───────────────────────────── Structure Logic ───────────────────┐
// └─────────────────────────────────────────────────────────────────┘

bool bullishBreak = not na(lastPH) and ta.crossover(close, lastPH)
bool bearishBreak = not na(lastPL) and ta.crossunder(close, lastPL)
bool isCHoCH      = (bullishBreak and trendState == -1) or (bearishBreak and trendState == 1)

if bullishBreak
    trendState := 1
else if bearishBreak
    trendState := -1

float atr = ta.atr(14)
float buffer = atr * sensitivity
float entryLabelOffset = atr * entryTextOffsetAtr

if isCHoCH
    if latestOnly
        if not na(activeLevelLine)
            line.delete(activeLevelLine)
        if not na(activeRetestBox)
            box.delete(activeRetestBox)
        if not na(activeStructLbl)
            label.delete(activeStructLbl)
        if not na(activeBreakLine)
            line.delete(activeBreakLine)

    activeLevel    := bullishBreak ? lastPH : lastPL
    activeDir      := bullishBreak ? 1 : -1
    activeStartIdx := activeDir == 1 ? lastPHIndex : lastPLIndex
    levelConsumed  := false
    hasLeftLevel   := false
    lastCHoCHBar   := bar_index

    wasInBandPrev := false
    entryTriggeredThisTouch := false
    retestCount := 0

    breakoutDelta  := candleDelta
    breakoutStrong := useDeltaAnalysis ? math.abs(breakoutDelta) > deltaMa * deltaThresh : false
    retestCvd      := 0.0

    color themeCol = activeDir == 1 ? bullCol : bearCol
    string baseChText = compactLabels ? "CH" : "CHoCH"
    string strengthTxt = showDeltaOnCH and useDeltaAnalysis ? (breakoutStrong ? "+" : "-") : ""

    activeLevelLine := line.new(
         bar_index, activeLevel,
         bar_index, activeLevel,
         color = themeCol,
         style = line.style_solid,
         width = 2
     )

    activeRetestBox := box.new(
         bar_index, activeLevel + buffer,
         bar_index, activeLevel - buffer,
         bgcolor = color.new(themeCol, zoneTransparency),
         border_color = color.new(themeCol, 100),
         border_style = line.style_solid,
         border_width = 0
     )

    if showBreakLevelLine and not na(activeStartIdx)
        activeBreakLine := line.new(
             activeStartIdx, activeLevel,
             bar_index, activeLevel,
             color = color.new(themeCol, 50),
             style = line.style_dashed,
             width = 1
         )

    if showStructureLabel and not na(activeStartIdx)
        int midX = math.round((activeStartIdx + bar_index) / 2)
        activeStructLbl := label.new(
             midX, activeLevel,
             baseChText + strengthTxt,
             style = label.style_none,
             color = #00000000,
             textcolor = themeCol,
             size = f_labelSize(chochTextSizeOpt)
         )

// ┌───────────────────────────── Retest Logic ──────────────────────┐
// └─────────────────────────────────────────────────────────────────┘

if not na(activeLevelLine)
    line.set_x2(activeLevelLine, bar_index)

if not na(activeRetestBox)
    box.set_right(activeRetestBox, bar_index)
    box.set_top(activeRetestBox, activeLevel + buffer)
    box.set_bottom(activeRetestBox, activeLevel - buffer)

float volMa        = ta.sma(volume, volMaLen)
bool  volumeOK     = not requireVol or volume > volMa * volThresh
bool  priceAtLevel = false

if not na(activeLevel)
    priceAtLevel := low <= activeLevel + buffer and high >= activeLevel - buffer

    if useDeltaAnalysis and priceAtLevel
        retestCvd += candleDelta

    if not hasLeftLevel and bar_index > lastCHoCHBar
        if (activeDir == 1 and low > activeLevel + buffer) or (activeDir == -1 and high < activeLevel - buffer)
            hasLeftLevel := true

// ┌───────────────────────────── Entry Logic ───────────────────────┐
// └─────────────────────────────────────────────────────────────────┘

bool respectsLevel = activeDir == 1 ? close > activeLevel : close < activeLevel
bool bullCandleOK  = not requireCandle or close > open
bool bearCandleOK  = not requireCandle or close < open

bool validEntryBar = bar_index > lastCHoCHBar and hasLeftLevel

bool leftBandNow = not priceAtLevel and wasInBandPrev
if leftBandNow
    entryTriggeredThisTouch := false

bool touchCycleActive = validEntryBar and priceAtLevel and not entryTriggeredThisTouch
bool reentryAllowed   = allowReEntry or retestCount == 0

bool bullTouchConfirm = activeDir == 1 and touchCycleActive and reentryAllowed and respectsLevel and bullCandleOK and volumeOK
bool bearTouchConfirm = activeDir == -1 and touchCycleActive and reentryAllowed and respectsLevel and bearCandleOK and volumeOK

bool bullCOLConfirm = activeDir == 1 and touchCycleActive and reentryAllowed and close > activeLevel + buffer and bullCandleOK and volumeOK
bool bearCOLConfirm = activeDir == -1 and touchCycleActive and reentryAllowed and close < activeLevel - buffer and bearCandleOK and volumeOK

bool bullEngulfConfirm = activeDir == 1 and touchCycleActive and reentryAllowed and close > open and close >= high[1] and open <= close[1] and volumeOK
bool bearEngulfConfirm = activeDir == -1 and touchCycleActive and reentryAllowed and close < open and close <= low[1] and open >= close[1] and volumeOK

bool bullSelectedConfirm = switch confirmMode
    "Touch"               => bullTouchConfirm
    "Close Outside Level" => bullCOLConfirm
    => bullEngulfConfirm

bool bearSelectedConfirm = switch confirmMode
    "Touch"               => bearTouchConfirm
    "Close Outside Level" => bearCOLConfirm
    => bearEngulfConfirm

bool bullEntry = not levelConsumed and bullSelectedConfirm
bool bearEntry = not levelConsumed and bearSelectedConfirm

if bullEntry or bearEntry
    entryTriggeredThisTouch := true
    retestCount += 1

    if not na(activeRetestBox) and fadeUsedZone
        box.set_bgcolor(activeRetestBox, color.new(activeDir == 1 ? bullCol : bearCol, usedTransparency))

    if not allowReEntry
        levelConsumed := true

    if showEntryLabels
        bool deltaSupportsTrend = activeDir == 1 ? retestCvd > 0 : retestCvd < 0
        string deltaTag = useDeltaAnalysis and showDeltaText ? f_deltaTag(breakoutStrong, deltaSupportsTrend) : ""

        label.new(
             bar_index,
             activeDir == 1 ? low - entryLabelOffset : high + entryLabelOffset,
             f_entryText(confirmMode) + deltaTag,
             style = label.style_none,
             color = #00000000,
             textcolor = activeDir == 1 ? bullCol : bearCol,
             size = f_labelSize(entryTextSizeOpt)
         )

wasInBandPrev := priceAtLevel

// ┌───────────────────────────── Alerts ────────────────────────────┐
// └─────────────────────────────────────────────────────────────────┘

bool fireCHoCH     = alertsOnCHoCH and isCHoCH
bool fireBullEntry = alertsOnBullEntry and bullEntry
bool fireBearEntry = alertsOnBearEntry and bearEntry

if fireCHoCH or fireBullEntry or fireBearEntry
    alert("Structure Retest Signal: " + (fireCHoCH ? "CHoCH" : fireBullEntry ? "Bull Entry" : "Bear Entry"), alert.freq_once_per_bar_close)

// ┌───────────────────────────── Visuals ───────────────────────────┐
// └─────────────────────────────────────────────────────────────────┘

plotshape(showChochTriangle and bullishBreak and trendState == 1 and isCHoCH and chochTriSizeOpt == "Tiny",   title = "Bull CHoCH Tiny",   style = shape.triangleup,   location = location.belowbar, color = bullCol, size = size.tiny)
plotshape(showChochTriangle and bullishBreak and trendState == 1 and isCHoCH and chochTriSizeOpt == "Small",  title = "Bull CHoCH Small",  style = shape.triangleup,   location = location.belowbar, color = bullCol, size = size.small)
plotshape(showChochTriangle and bullishBreak and trendState == 1 and isCHoCH and chochTriSizeOpt == "Normal", title = "Bull CHoCH Normal", style = shape.triangleup,   location = location.belowbar, color = bullCol, size = size.normal)

plotshape(showChochTriangle and bearishBreak and trendState == -1 and isCHoCH and chochTriSizeOpt == "Tiny",   title = "Bear CHoCH Tiny",   style = shape.triangledown, location = location.abovebar, color = bearCol, size = size.tiny)
plotshape(showChochTriangle and bearishBreak and trendState == -1 and isCHoCH and chochTriSizeOpt == "Small",  title = "Bear CHoCH Small",  style = shape.triangledown, location = location.abovebar, color = bearCol, size = size.small)
plotshape(showChochTriangle and bearishBreak and trendState == -1 and isCHoCH and chochTriSizeOpt == "Normal", title = "Bear CHoCH Normal", style = shape.triangledown, location = location.abovebar, color = bearCol, size = size.normal)

plotshape(showEntryTriangle and bullEntry and entrySizeOpt == "Tiny",   title = "Bull Entry Tiny",   style = shape.triangleup,   location = location.belowbar, color = bullCol, size = size.tiny)
plotshape(showEntryTriangle and bullEntry and entrySizeOpt == "Small",  title = "Bull Entry Small",  style = shape.triangleup,   location = location.belowbar, color = bullCol, size = size.small)
plotshape(showEntryTriangle and bullEntry and entrySizeOpt == "Normal", title = "Bull Entry Normal", style = shape.triangleup,   location = location.belowbar, color = bullCol, size = size.normal)

plotshape(showEntryTriangle and bearEntry and entrySizeOpt == "Tiny",   title = "Bear Entry Tiny",   style = shape.triangledown, location = location.abovebar, color = bearCol, size = size.tiny)
plotshape(showEntryTriangle and bearEntry and entrySizeOpt == "Small",  title = "Bear Entry Small",  style = shape.triangledown, location = location.abovebar, color = bearCol, size = size.small)
plotshape(showEntryTriangle and bearEntry and entrySizeOpt == "Normal", title = "Bear Entry Normal", style = shape.triangledown, location = location.abovebar, color = bearCol, size = size.normal)

barcolor(colorBarsByTrend ? (trendState == 1 ? bullCol : trendState == -1 ? bearCol : na) : na)

Overview

Confirmation can be a touch, a close outside the level or an engulfing candle, with optional volume and directional candle requirements. A relative volume delta proxy rates breakout conviction and retest sentiment. Settings control showing only the latest structure, re-entries in the same zone, labels, triangles, bar colouring and alerts.

Details

Published by

Focal-QuantAI on GitHub

Draws

On the price chart

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
Pivot Lengthint5pivotLen
Retest Sensitivity (ATR %)float0.5sensitivity
Show Latest OnlybooltruelatestOnly
Allow Re-Entries In Same ZoneboolfalseallowReEntry
Enable Delta AnalysisbooltrueuseDeltaAnalysis
Delta MA Periodint20deltaMaLen
Run Away Threshold (xMA)float1.5deltaThresh
Show Delta Insight In Entry TextbooltrueshowDeltaText
Show Strong/Weak On CHoCH LabelbooltrueshowDeltaOnCH
Confirmation ModestringEngulfingconfirmMode
Volume MA Lengthint20volMaLen
Volume Thresholdfloat1.30volThresh
Show all 34 settings
SettingTypeDefaultVariable
Require Volume FilterboolfalserequireVol
Require Directional CandleboolfalserequireCandle
BullishcolorBULL_COLORbullCol
BearishcolorBEAR_COLORbearCol
Show CHoCH LabelsbooltrueshowStructureLabel
Compact LabelsbooltruecompactLabels
Show Entry TextbooltrueshowEntryLabels
Color Bars By TrendbooltruecolorBarsByTrend
Fade Used LevelsbooltruefadeUsedZone
Active Transparencyint85zoneTransparency
Used Transparencyint95usedTransparency
Entry Triangle SizestringTinyentrySizeOpt
Show Break Level LinebooltrueshowBreakLevelLine
Show CHoCH TrianglebooltrueshowChochTriangle
CHoCH Triangle SizestringTinychochTriSizeOpt
Show Entry TrianglebooltrueshowEntryTriangle
Entry Text Offset (ATR)float0.60entryTextOffsetAtr
Entry Text SizestringTinyentryTextSizeOpt
CHoCH Text SizestringSmallchochTextSizeOpt
Include CHoCH In AlertbooltruealertsOnCHoCH
Include Bull Entry In AlertbooltruealertsOnBullEntry
Include Bear Entry In AlertbooltruealertsOnBearEntry
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

Moon Dev GEX Sweep & CVD

by moondevonyt
92 stars

The indicator detects liquidity sweeps across key price levels and calculates a cumulative volume delta proxy. It uses pivot high and low lookbacks to identify swing points, marking sweeps when price breaks beyond a level and quickly closes back inside. Featur

Indicator v5 Support & resistanceSMC / ICT / price action
Updated 2 months ago · Custom licence GitHub repository of Moon Dev GEX Sweep & CVD

Calculates higher-timeframe volume profiles to identify Value Area High (VAH), Value Area Low (VAL), and Point of Control (POC) levels directly on the price chart. It flags potential reversal setups and Change in State of Delivery (CISD) patterns relative to v

Indicator v6 VolumeSupport & resistance
Updated 2 months ago · None stated GitHub repository of CandelaCharts - Value Area Reversals

Copilot

by milocaetano
48 stars

Copilot is an order flow range-reversal indicator designed to overlay trading setups directly on the price chart. It evaluates four criteria: market context (sideways vs trending regime based on ATR height), structure (double top or double bottom retests), abs

Indicator v5 SMC / ICT / price actionSupport & resistance
Updated 3 days ago · MIT GitHub repository of Copilot

Supply and Demand Visible Range identifies supply, demand, and equilibrium zones across the visible chart range. It accumulates high, low, and volume data starting from the leftmost visible bar, optionally requesting lower timeframe intrabar data for finer res

Indicator v5 Support & resistanceVolume Repaints
Updated 2 months ago · AGPL-3.0 GitHub repository of Supply and Demand Visible Range [LuxAlgo]
13 stars

This script identifies and visualizes bullish and bearish order blocks on the price chart. It detects low-volatility consolidation ranges followed by breakout moves accompanied by high trading volume. Users can select between Simple, Relative, or Weighted volu

Indicator v6 SMC / ICT / price actionSupport & resistance
Updated 6 months ago · MIT GitHub repository of Advanced Order Blocks with Volume

This indicator identifies and visualizes key support and resistance heatmap zones directly on the price chart. Using closed one-hour price data, it evaluates multi-scale pivots, liquidity clusters, relative volume, and round-number resonances to score structur

Indicator v6 Support & resistanceSMC / ICT / price action
Updated 7 weeks ago · MIT GitHub repository of 加密货币1小时关键价位热力图 V2

More SMC / ICT scripts

Related on ForexR

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers