Indicator · Pine Script v5 · On the chart

Vdubus Pattern Gen V2

by eddiebelaval· code credited to Bespoke_Analysis_Engine

Vdubus Pattern Gen V2 is a TradingView indicator that identifies and plots chart patterns, harmonic shapes, and structural reversals based on multi-scale ZigZag structures and smoothed momentum physics.

View on GitHub

Repaints

GitHub stars7on the repository
Pine versionv5runs as is
Lines of code366
Settings32inputs
LicenceNone statedfile: MPL-2.0
Last update3 months ago24 Jul 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

366 lines of Pine Script v5 from pinescript/editors_picks/vdubus-divergence-wave-pattern-generator-v1.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

vdubus-divergence-wave-pattern-generator-v1.pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Bespoke_Analysis_Engine

//@version=5
indicator("Vdubus Pattern Gen V2 [Restored & Refined]", shorttitle="Vdubus Gen V2", overlay=true, max_lines_count=500, max_labels_count=500, max_boxes_count=500)

// ==========================================
// 1. SETTINGS
// ==========================================

// --- FAST STRUCTURE (Current/Entry) ---
grp_fast = "Fast Structure (Entry Geometry)"
fastDepth = input.int(9, title="Fast Pattern Scale (ZigZag)", group=grp_fast)
showFastLines = input.bool(false, title="Show Fast Lines", group=grp_fast)
showFastFills = input.bool(true, title="Show Fast Fills", group=grp_fast)
showFastLbl   = input.bool(false, title="Show Fast Labels", group=grp_fast)

// --- SLOW STRUCTURE (Macro/Context) ---
grp_slow = "Slow Structure (Macro Context)"
slowDepth = input.int(24, title="Slow Pattern Scale (ZigZag)", group=grp_slow)
showSlowLines = input.bool(true, title="Show Slow Lines", group=grp_slow)
showSlowFills = input.bool(true, title="Show Slow Fills", group=grp_slow)
showSlowLbl   = input.bool(true, title="Show Slow Labels", group=grp_slow)

// --- PROJECTION TARGETS ---
grp_tgt   = "Target Projections"
showTgtBox = input.bool(false, title="Show Target Box (Prev H/L)", tooltip="Draws target box to the previous structural High/Low (Point C).", group=grp_tgt)

// --- MOMENTUM PHYSICS ---
grp_macd  = "Momentum Physics (Smoothed Defaults)"
fastLen   = input.int(21, title="Fast Length", group=grp_macd)  
slowLen   = input.int(34, title="Slow Length", group=grp_macd) 
sigLen    = input.int(5, title="Signal Length", group=grp_macd) 
lookback  = input.int(3, title="Momentum Pivot Lookback", group=grp_macd) 

// --- STYLES ---
grp_style = "Style & Colors"
col_bear   = input.color(color.red, title="Bearish Standard", group=grp_style)
col_bull   = input.color(color.green, title="Bullish Standard", group=grp_style)
col_climax = input.color(color.orange, title="Climax (Trap)", group=grp_style)
col_round  = input.color(color.navy, title="Rounded Top/Bottom", group=grp_style)
col_pred   = input.color(color.purple, title="Predator (Hidden)", group=grp_style)

// --- PATTERN TOGGLES ---
grp_pats  = "Pattern Filters"
showStandard = input.bool(true, title="Show Standard Reversals", group=grp_pats)
showClimax   = input.bool(true, title="Show Climax Reversals", group=grp_pats)
showRounded  = input.bool(true, title="Show Rounded Patterns", group=grp_pats)
showPred     = input.bool(true, title="Show Predator (Hidden)", group=grp_pats)

grp_harm  = "Harmonic Shape Selectors"
showGartley = input.bool(false, title="Gartley", group=grp_harm)
showBat     = input.bool(false, title="Bat", group=grp_harm)
showButterfly = input.bool(false, title="Butterfly", group=grp_harm)
showCrab    = input.bool(false, title="Crab", group=grp_harm)
showDeep    = input.bool(false, title="Deep/Shark", group=grp_harm)
showHS      = input.bool(true, title="Head & Shoulders", group=grp_harm)
err_tol     = input.float(0.15, title="Harmonic Tolerance", minval=0.01, maxval=0.5, group=grp_harm)

// --- DASHBOARD ---
grp_dash  = "Confluence Dashboard"
showDash  = input.bool(false, title="Show Dashboard", group=grp_dash)
dashPos   = input.string("Bottom Right", title="Position", options=["Top Right", "Bottom Right", "Top Left", "Bottom Left"], group=grp_dash)
textSize  = input.string("Small", title="Size", options=["Small", "Normal", "Large"], group=grp_dash)

// ==========================================
// 2. MOMENTUM CALCULATIONS
// ==========================================
[macdLine, signalLine, histLine] = ta.macd(close, fastLen, slowLen, sigLen)

ph_mom = ta.pivothigh(histLine, lookback, lookback)
pl_mom = ta.pivotlow(histLine, lookback, lookback)

var waveHighs_val = array.new_float()
var waveHighs_loc = array.new_int()
var waveLows_val = array.new_float()
var waveLows_loc = array.new_int()

if not na(ph_mom)
    array.unshift(waveHighs_val, ph_mom)
    array.unshift(waveHighs_loc, bar_index[lookback]) 
    if array.size(waveHighs_val) > 10 
        array.pop(waveHighs_val)
        array.pop(waveHighs_loc)

if not na(pl_mom)
    array.unshift(waveLows_val, pl_mom)
    array.unshift(waveLows_loc, bar_index[lookback]) 
    if array.size(waveLows_val) > 10 
        array.pop(waveLows_val)
        array.pop(waveLows_loc)

// --- MOMENTUM VALIDATION ---
f_checkStandardBearish() =>
    valid = false
    if array.size(waveHighs_val) >= 3
        m1 = array.get(waveHighs_val, 2), m2 = array.get(waveHighs_val, 1), m3 = array.get(waveHighs_val, 0)
        if m2 < m1 and m3 <= m2 
            valid := true
    valid

f_checkStandardBullish() =>
    valid = false
    if array.size(waveLows_val) >= 3
        m1 = array.get(waveLows_val, 2), m2 = array.get(waveLows_val, 1), m3 = array.get(waveLows_val, 0)
        if m2 > m1 and m3 >= m2 
            valid := true
    valid

f_checkClimaxBearish() =>
    valid = false
    if array.size(waveHighs_val) >= 3
        m1 = array.get(waveHighs_val, 2), m2 = array.get(waveHighs_val, 1), m3 = array.get(waveHighs_val, 0)
        if m2 >= m1 and m3 < m2
            valid := true
    valid

f_checkClimaxBullish() =>
    valid = false
    if array.size(waveLows_val) >= 3
        m1 = array.get(waveLows_val, 2), m2 = array.get(waveLows_val, 1), m3 = array.get(waveLows_val, 0)
        if m2 <= m1 and m3 > m2
            valid := true
    valid

f_checkRoundedBearish() =>
    valid = false
    if array.size(waveHighs_val) >= 4
        m1 = array.get(waveHighs_val, 3), m2 = array.get(waveHighs_val, 2)
        m3 = array.get(waveHighs_val, 1), m4 = array.get(waveHighs_val, 0)
        if m1 > m2 and m2 > m3 and m3 > m4
            valid := true
    valid

f_checkRoundedBullish() =>
    valid = false
    if array.size(waveLows_val) >= 4
        m1 = array.get(waveLows_val, 3), m2 = array.get(waveLows_val, 2)
        m3 = array.get(waveLows_val, 1), m4 = array.get(waveLows_val, 0)
        if m1 < m2 and m2 < m3 and m3 < m4
            valid := true
    valid

f_checkBearishPredator() =>
    valid = false
    if array.size(waveHighs_val) >= 2
        m2 = array.get(waveHighs_val, 1), m3 = array.get(waveHighs_val, 0)
        if m3 > m2 
            valid := true
    valid

f_checkBullishPredator() =>
    valid = false
    if array.size(waveLows_val) >= 2
        m2 = array.get(waveLows_val, 1), m3 = array.get(waveLows_val, 0)
        if m3 < m2 
            valid := true
    valid

// ==========================================
// 3. DRAWING & IDENTIFICATION
// ==========================================

f_getHarmonicName(xB_ratio, xD_ratio, isBullish) =>
    name = "Unknown" 
    if math.abs(xB_ratio - 0.618) < err_tol and math.abs(xD_ratio - 0.786) < err_tol
        name := "Gartley"
    else if xB_ratio >= 0.382 - err_tol and xB_ratio <= 0.5 + err_tol and math.abs(xD_ratio - 0.886) < err_tol
        name := "Bat"
    else if math.abs(xB_ratio - 0.786) < err_tol and xD_ratio >= 1.27 - err_tol and xD_ratio <= 1.618 + err_tol
        name := "Butterfly"
    else if xB_ratio >= 0.382 - err_tol and xB_ratio <= 0.618 + err_tol and math.abs(xD_ratio - 1.618) < err_tol
        name := "Crab"
    else if xD_ratio > 1.0
        name := "Deep Pattern"
    else
        name := "Retracement"
    name

f_drawStruct(indices, values, col, patName, isPredator, isBullish, doLines, doFills, doLbl) =>
    xD = array.get(indices, 0), yD = array.get(values, 0)
    
    // Draw Lines & Fills
    if doLines or doFills
        xX = array.get(indices, 4), yX = array.get(values, 4)
        xA = array.get(indices, 3), yA = array.get(values, 3)
        xB = array.get(indices, 2), yB = array.get(values, 2)
        xC = array.get(indices, 1), yC = array.get(values, 1)
        
        w = isPredator ? 2 : 1 
        
        if doLines
            line.new(xX, yX, xA, yA, color=col, width=w)
            line.new(xA, yA, xB, yB, color=col, width=w)
            line.new(xB, yB, xC, yC, color=col, width=w)
            line.new(xC, yC, xD, yD, color=col, width=w)
        
        if doFills
            l_xa = line.new(xX, yX, xA, yA, color=color.new(col, 100), width=0)
            l_xb = line.new(xX, yX, xB, yB, color=color.new(col, 100), width=0)
            l_bc = line.new(xB, yB, xC, yC, color=color.new(col, 100), width=0)
            l_bd = line.new(xB, yB, xD, yD, color=color.new(col, 100), width=0)
            
            linefill.new(l_xa, l_xb, color.new(col, 92)) 
            linefill.new(l_bc, l_bd, color.new(col, 92))

    // Draw Labels
    if doLbl
        sty = isBullish ? label.style_label_up : label.style_label_down
        label.new(xD, yD, patName, color=col, textcolor=color.white, style=sty, size=size.small)

    // Draw Target Box (Updated: Previous H/L)
    if showTgtBox
        // For standard M/W patterns, point C (Index 1) is the "Previous H/L" inside the structure.
        yC = array.get(values, 1)
        
        boxTop = isBullish ? yC : yD
        boxBot = isBullish ? yD : yC
        
        box.new(xD, boxTop, xD + 20, boxBot, border_color=color.new(col, 80), bgcolor=color.new(col, 95))

// ==========================================
// 4. MAIN LOGIC LOOP
// ==========================================
f_runEngine(depth, doLines, doFills, doLbl) =>
    var float[] zzP = array.new_float()
    var int[] zzL = array.new_int()
    
    ph = ta.pivothigh(high, depth, depth)
    pl = ta.pivotlow(low, depth, depth)
    
    if not na(ph)
        array.unshift(zzP, ph)
        array.unshift(zzL, bar_index[depth])
        if array.size(zzP) > 10 
            array.pop(zzP), array.pop(zzL)
        
        if array.size(zzP) >= 5
            yD = array.get(zzP, 0), yX = array.get(zzP, 4)
            yC = array.get(zzP, 1), yB = array.get(zzP, 2), yA = array.get(zzP, 3)
            
            // Calc Ratios
            xa_len = math.abs(yA - yX)
            ab_len = math.abs(yB - yA)
            xb_ratio = xa_len != 0 ? ab_len / xa_len : 0.0
            
            rawName = f_getHarmonicName(xb_ratio, 1.27, false)
            isHS = showHS and (yB > yX and yB > yD)
            
            // Check Toggles
            shouldDraw = false
            if isHS
                shouldDraw := true
            else 
                if rawName == "Gartley" and showGartley
                    shouldDraw := true
                else if rawName == "Bat" and showBat
                    shouldDraw := true
                else if rawName == "Butterfly" and showButterfly
                    shouldDraw := true
                else if rawName == "Crab" and showCrab
                    shouldDraw := true
                else if rawName == "Deep Pattern" and showDeep
                    shouldDraw := true
                else if rawName == "Retracement" // Generic fallback
                    shouldDraw := true

            // 1. Standard
            if showStandard and f_checkStandardBearish() and shouldDraw
                pat = isHS ? "Bearish H&S" : ("Bearish " + rawName)
                f_drawStruct(zzL, zzP, col_bear, pat, false, false, doLines, doFills, doLbl)
            
            // 2. Climax
            if showClimax and f_checkClimaxBearish()
                f_drawStruct(zzL, zzP, col_climax, "CLIMAX REVERSAL", false, false, doLines, doFills, doLbl)
                
            // 3. Rounded
            if showRounded and f_checkRoundedBearish() and doLbl
                label.new(bar_index[depth], yD, "ROUNDED TOP", color=col_round, style=label.style_label_down, size=size.small)
                
            // 4. Predator
            if showPred and not f_checkStandardBearish() and yD < yX
                if f_checkBearishPredator()
                    f_drawStruct(zzL, zzP, col_pred, "🦖 PREDATOR", true, false, doLines, doFills, doLbl)

    if not na(pl)
        array.unshift(zzP, pl)
        array.unshift(zzL, bar_index[depth])
        if array.size(zzP) > 10 
            array.pop(zzP), array.pop(zzL)
            
        if array.size(zzP) >= 5
            yD = array.get(zzP, 0), yX = array.get(zzP, 4)
            yC = array.get(zzP, 1), yB = array.get(zzP, 2), yA = array.get(zzP, 3)
            
            xa_len = math.abs(yA - yX)
            ab_len = math.abs(yB - yA)
            xb_ratio = xa_len != 0 ? ab_len / xa_len : 0.0
            
            rawName = f_getHarmonicName(xb_ratio, 1.27, true)
            isInvHS = showHS and (yB < yX and yB < yD)
            
            shouldDraw = false
            if isInvHS
                shouldDraw := true
            else 
                if rawName == "Gartley" and showGartley
                    shouldDraw := true
                else if rawName == "Bat" and showBat
                    shouldDraw := true
                else if rawName == "Butterfly" and showButterfly
                    shouldDraw := true
                else if rawName == "Crab" and showCrab
                    shouldDraw := true
                else if rawName == "Deep Pattern" and showDeep
                    shouldDraw := true
                else if rawName == "Retracement"
                    shouldDraw := true

            // 1. Standard
            if showStandard and f_checkStandardBullish() and shouldDraw
                pat = isInvHS ? "Bullish Inv H&S" : ("Bullish " + rawName)
                f_drawStruct(zzL, zzP, col_bull, pat, false, true, doLines, doFills, doLbl)
            
            // 2. Climax
            if showClimax and f_checkClimaxBullish()
                f_drawStruct(zzL, zzP, col_climax, "CLIMAX REVERSAL", false, true, doLines, doFills, doLbl)
            
            // 3. Rounded
            if showRounded and f_checkRoundedBullish() and doLbl
                label.new(bar_index[depth], yD, "ROUNDED BOTTOM", color=col_round, style=label.style_label_up, size=size.small)
                
            // 4. Predator
            if showPred and not f_checkStandardBullish() and yD > yX
                if f_checkBullishPredator()
                    f_drawStruct(zzL, zzP, col_pred, "🦖 PREDATOR", true, true, doLines, doFills, doLbl)

// --- EXECUTE ENGINES ---
f_runEngine(fastDepth, showFastLines, showFastFills, showFastLbl)
f_runEngine(slowDepth, showSlowLines, showSlowFills, showSlowLbl)

// ==========================================
// 5. DASHBOARD
// ==========================================
if showDash
    pos = (dashPos == "Top Right") ? position.top_right : (dashPos == "Bottom Right") ? position.bottom_right : (dashPos == "Top Left") ? position.top_left : position.bottom_left
    sz = (textSize == "Small") ? size.small : (textSize == "Large") ? size.large : size.normal
    
    var table d = table.new(pos, 2, 2, bgcolor=color.new(color.black, 50), border_color=color.white, border_width=1)
    if barstate.islast
        table.cell(d, 0, 0, "Opposing Force", text_color=color.white, text_size=sz)
        
        last_bull_mom = array.size(waveLows_val) > 0 ? array.get(waveLows_val, 0) : 0.0
        last_bear_mom = array.size(waveHighs_val) > 0 ? array.get(waveHighs_val, 0) : 0.0
        
        opp_state = "Neutral"
        opp_col = color.gray
        
        if math.abs(last_bull_mom) > math.abs(last_bear_mom)
            opp_state := "Bulls Strong"
            opp_col := color.green
        else
            opp_state := "Bears Strong"
            opp_col := color.red
            
        table.cell(d, 1, 0, opp_state, text_color=color.white, bgcolor=opp_col, text_size=sz)

Overview

Vdubus Pattern Gen V2 draws fast entry structures, slow macro context structures, target boxes, and a confluence dashboard directly on the price chart. Users can customize fast and slow pattern scales, momentum lengths, harmonic tolerances, and toggle specific pattern types such as standard reversals, climax traps, rounded formations, and harmonic shapes. The indicator relies on ZigZag calculations, which inherently repaint as new price extremes form on live bars.

Details

Published by

eddiebelaval on GitHub

Code credit

Bespoke_Analysis_Engine, as written in the script's header

Type

Indicator, Pine Script v5

Draws

On the price chart

Category

Trend, Support & resistance, Screeners & dashboards

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

  • Signals can change on the live bar or after it closes (repainting)

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Fast Pattern Scale (ZigZag)int9fastDepth
Show Fast LinesboolfalseshowFastLines
Show Fast FillsbooltrueshowFastFills
Show Fast LabelsboolfalseshowFastLbl
Slow Pattern Scale (ZigZag)int24slowDepth
Show Slow LinesbooltrueshowSlowLines
Show Slow FillsbooltrueshowSlowFills
Show Slow LabelsbooltrueshowSlowLbl
Show Target Box (Prev H/L)boolfalseshowTgtBox
Fast Lengthint21fastLen
Slow Lengthint34slowLen
Signal Lengthint5sigLen
Show all 32 settings
SettingTypeDefaultVariable
Momentum Pivot Lookbackint3lookback
Bearish Standardcolorcolor.redcol_bear
Bullish Standardcolorcolor.greencol_bull
Climax (Trap)colorcolor.orangecol_climax
Rounded Top/Bottomcolorcolor.navycol_round
Predator (Hidden)colorcolor.purplecol_pred
Show Standard ReversalsbooltrueshowStandard
Show Climax ReversalsbooltrueshowClimax
Show Rounded PatternsbooltrueshowRounded
Show Predator (Hidden)booltrueshowPred
GartleyboolfalseshowGartley
BatboolfalseshowBat
ButterflyboolfalseshowButterfly
CrabboolfalseshowCrab
Deep/SharkboolfalseshowDeep
Head & ShouldersbooltrueshowHS
Harmonic Tolerancefloat0.15err_tol
Show DashboardboolfalseshowDash
PositionstringBottom RightdashPos
SizestringSmalltextSize
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

257 stars

This indicator overlays an intraday SPX and ES chart with a midnight session range, regular-trading-hours opening levels, and a VWAP projection box. It draws the midnight high, mid, and low, flags edge rejections within an absolute tolerance, and plots optiona

Indicator v6 TrendSupport & resistance
Updated 6 weeks ago · None stated GitHub repository of SPX Midnight Box + Snag Logic
53 stars

Apex Trend & Liquidity Master calculates a trend cloud using customizable moving averages expanded by a volatility multiplier directly on the main price chart. It identifies dynamic support and resistance liquidity zones from swing high and low pivots, extendi

Indicator v6 TrendSupport & resistance
Updated 2 months ago · MPL-2.0 GitHub repository of Apex Trend & Liquidity Master

Market Monitor - 1m

by chris-c-thomas
14 stars

Market Monitor - 1m is an overlay indicator designed for multi-chart monitoring and directional bias assessment. It plots a fast, mid, and slow EMA ribbon with a fill cloud, session VWAP with standard deviation bands, and previous day key levels. It evaluates

Indicator v6 TrendMoving averages Repaints
Updated 6 months ago · MIT GitHub repository of Market Monitor - 1m
13 stars

The Adaptive Trend Finder calculates logarithmic linear regression channels overlaid on the price chart. Operating on the most recent historical bar, it fits a log-transformed regression line and standard deviation bands. It evaluates linear correlation using

Indicator v6 TrendSupport & resistance Repaints
Updated 6 months ago · MIT GitHub repository of Adaptive Trend Finder (log)

5 EMAs

by hirawatt
11 stars

5 EMAs calculates and plots five Exponential Moving Averages derived from five configurable timeframes directly onto the main price chart. It also plots the high and low lines fetched from an additional custom timeframe, accompanied by a small on-screen table

Indicator v4 Moving averagesTrend Repaints
Updated 2 years ago · MIT GitHub repository of 5 EMAs
9 stars

Adaptive Supertrend is an overlay indicator that dynamically adjusts its Supertrend band width using a composite conviction score. Conviction is derived from ATR percentile ranking, trend force from EMA distance, and chop detection, narrowing the bands during

Indicator v6 TrendVolatility & bands
Updated yesterday · MIT GitHub repository of Adaptive Supertrend

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