Indicator · Pine Script v6 · On the chart

BOS & CHoCH [AFTHAB]

by kvmafthab-pixel· code credited to AFTHAB

This overlay indicator detects market structure on the price chart with two layers at once: internal structure on a five-bar leg and swing structure with a configurable length.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code378
Settings24inputs
LicenceCustom licencefile: MPL-2.0
Last update5 months ago26 May 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

378 lines of Pine Script v6 from indicators/bos-choch-structure.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

bos-choch-structure.pine
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © AFTHAB — Structure detection adapted from LuxAlgo's Smart Money Concepts

//@version=6
indicator("BOS & CHoCH [AFTHAB]", overlay=true, max_lines_count=500, max_labels_count=500)

int BULL_LEG = 1
int BEAR_LEG = 0
int BULL     = 1
int BEAR     = -1

string modeInput   = input.string("Historical", "Mode", options=["Historical", "Present"], tooltip="Historical = all signals. Present = most recent only.", group="General")
bool   showTrend   = input.bool(false, "Color Candles by Trend", group="General")
int    maxBars     = input.int(400, "Max Historical Bars", minval=50, maxval=5000, step=50, group="General")

bool   showInternal   = input.bool(true, "Show Internal Structure", group="Internal Structure")
string showIntBull    = input.string("All", "Bullish", inline="ib", options=["All", "BOS", "CHoCH"], group="Internal Structure")
color  intBullCol     = input.color(#089981, "", inline="ib", group="Internal Structure")
string showIntBear    = input.string("All", "Bearish", inline="ibe", options=["All", "BOS", "CHoCH"], group="Internal Structure")
color  intBearCol     = input.color(#f23645, "", inline="ibe", group="Internal Structure")
bool   intConfluence  = input.bool(false, "Confluence Filter", group="Internal Structure")
string intLblSz       = input.string("Tiny", "Label Size", options=["Tiny", "Small", "Normal"], group="Internal Structure")

bool   showSwing      = input.bool(true, "Show Swing Structure", group="Swing Structure")
string showSwgBull    = input.string("All", "Bullish", inline="sb", options=["All", "BOS", "CHoCH"], group="Swing Structure")
color  swgBullCol     = input.color(#089981, "", inline="sb", group="Swing Structure")
string showSwgBear    = input.string("All", "Bearish", inline="sbe", options=["All", "BOS", "CHoCH"], group="Swing Structure")
color  swgBearCol     = input.color(#f23645, "", inline="sbe", group="Swing Structure")
string swgLblSz       = input.string("Small", "Label Size", options=["Tiny", "Small", "Normal"], group="Swing Structure")
bool   showSwgPts     = input.bool(false, "Show Swing Points", inline="sp", group="Swing Structure")
int    swgLength      = input.int(50, "", inline="sp", minval=10, group="Swing Structure")
bool   showHLSwings   = input.bool(true, "Show Strong/Weak High/Low", group="Swing Structure")

float  corrFactor     = input.float(0.382, "Correction Level (Fib)", minval=0.05, maxval=0.95, step=0.01, group="Correction / CHoCH")
string corrLnStyle    = input.string("Dashed", "Correction Line Style", options=["Solid", "Dashed", "Dotted"], group="Correction / CHoCH")
int    corrLnWidth    = input.int(1, "Correction Line Width", minval=1, maxval=3, group="Correction / CHoCH")
color  corrBullCol    = input.color(color.new(#089981, 40), "Bull Correction", group="Correction / CHoCH")
color  corrBearCol    = input.color(color.new(#f23645, 40), "Bear Correction", group="Correction / CHoCH")

getStyle(string s) =>
    switch s
        "Solid"  => line.style_solid
        "Dashed" => line.style_dashed
        =>          line.style_dotted

getSize(string s) =>
    switch s
        "Tiny"   => size.tiny
        "Normal" => size.normal
        =>          size.small

leg(int sz) =>
    var int l = 0
    if high[sz] > ta.highest(sz)
        l := BEAR_LEG
    else if low[sz] < ta.lowest(sz)
        l := BULL_LEG
    l

bool inRange = bar_index >= (last_bar_index - maxBars)

type Piv
    float level     = na
    float prevLevel = na
    bool  crossed   = false
    int   bTime     = 0
    int   bIdx      = 0

type Corr
    float level     = na
    int   startIdx  = na
    int   dir       = 0
    line  ln        = na
    bool  active    = false

type Trail
    float top       = na
    float bot       = na
    int   topTime   = 0
    int   botTime   = 0

var Piv  swgHi   = Piv.new()
var Piv  swgLo   = Piv.new()
var int  swgTr   = 0
var Corr swgCorr = Corr.new()

var Piv  intHi   = Piv.new()
var Piv  intLo   = Piv.new()
var int  intTr   = 0
var Corr intCorr = Corr.new()

var Trail trail  = Trail.new()

var line  presIntBosLn  = na,  var label presIntBosLb  = na
var line  presSwgBosLn  = na,  var label presSwgBosLb  = na
var line  presIntChLn   = na,  var label presIntChLb   = na
var line  presSwgChLn   = na,  var label presSwgChLb   = na
var line  presIntCorrLn = na,  var line  presSwgCorrLn = na

bool aIntBullBos  = false
bool aIntBearBos  = false
bool aIntBullCh   = false
bool aIntBearCh   = false
bool aSwgBullBos  = false
bool aSwgBearBos  = false
bool aSwgBullCh   = false
bool aSwgBearCh   = false

int swgLeg = leg(swgLength)

if ta.change(swgLeg) != 0
    if ta.change(swgLeg) == 1
        swgLo.prevLevel := swgLo.level
        swgLo.level     := low[swgLength]
        swgLo.crossed   := false
        swgLo.bTime     := time[swgLength]
        swgLo.bIdx      := bar_index[swgLength]
        trail.bot       := swgLo.level
        trail.botTime   := swgLo.bTime
        if showSwgPts and inRange
            string t = swgLo.level < nz(swgLo.prevLevel, swgLo.level + 1) ? "LL" : "HL"
            label.new(swgLo.bIdx, swgLo.level, t, xloc=xloc.bar_index, color=color.new(swgBullCol, 90), textcolor=swgBullCol, style=label.style_label_up, size=size.tiny)
    else
        swgHi.prevLevel := swgHi.level
        swgHi.level     := high[swgLength]
        swgHi.crossed   := false
        swgHi.bTime     := time[swgLength]
        swgHi.bIdx      := bar_index[swgLength]
        trail.top       := swgHi.level
        trail.topTime   := swgHi.bTime
        if showSwgPts and inRange
            string t = swgHi.level > nz(swgHi.prevLevel, swgHi.level - 1) ? "HH" : "LH"
            label.new(swgHi.bIdx, swgHi.level, t, xloc=xloc.bar_index, color=color.new(swgBearCol, 90), textcolor=swgBearCol, style=label.style_label_down, size=size.tiny)

int intLeg = leg(5)

if ta.change(intLeg) != 0
    if ta.change(intLeg) == 1
        intLo.prevLevel := intLo.level
        intLo.level     := low[5]
        intLo.crossed   := false
        intLo.bTime     := time[5]
        intLo.bIdx      := bar_index[5]
    else
        intHi.prevLevel := intHi.level
        intHi.level     := high[5]
        intHi.crossed   := false
        intHi.bTime     := time[5]
        intHi.bIdx      := bar_index[5]

if showInternal
    bool iBullBar = true
    bool iBearBar = true
    if intConfluence
        iBullBar := high - math.max(close, open) > math.min(close, open) - low
        iBearBar := high - math.max(close, open) < math.min(close, open) - low

    bool intHiExtra = intHi.level != swgHi.level and iBullBar
    if ta.crossover(close, intHi.level) and not intHi.crossed and intHiExtra
        intHi.crossed := true
        if intTr == BULL or intTr == 0
            aIntBullBos := true
            bool showBos = showIntBull == "All" or showIntBull == "BOS"
            if showBos and inRange
                if modeInput == "Present"
                    line.delete(presIntBosLn)
                    label.delete(presIntBosLb)
                int mid = math.round(math.avg(intHi.bIdx, bar_index))
                presIntBosLn := line.new(intHi.bIdx, intHi.level, bar_index, intHi.level, xloc=xloc.bar_index, color=intBullCol, style=line.style_dashed)
                presIntBosLb := label.new(mid, intHi.level, "BOS", xloc=xloc.bar_index, color=color(na), textcolor=intBullCol, style=label.style_label_down, size=getSize(intLblSz))
            if not na(intLo.level)
                if not na(intCorr.ln)
                    line.delete(intCorr.ln)
                float imp       = intHi.level - intLo.level
                intCorr.level   := intHi.level - corrFactor * imp
                intCorr.startIdx := bar_index
                intCorr.dir     := BULL
                intCorr.active  := true
                if inRange
                    intCorr.ln := line.new(bar_index, intCorr.level, bar_index + 1, intCorr.level, xloc=xloc.bar_index, color=corrBullCol, width=corrLnWidth, style=getStyle(corrLnStyle), extend=extend.right)
            if intTr == 0
                intTr := BULL

    bool intLoExtra = intLo.level != swgLo.level and iBearBar
    if ta.crossunder(close, intLo.level) and not intLo.crossed and intLoExtra
        intLo.crossed := true
        if intTr == BEAR or intTr == 0
            aIntBearBos := true
            bool showBos = showIntBear == "All" or showIntBear == "BOS"
            if showBos and inRange
                if modeInput == "Present"
                    line.delete(presIntBosLn)
                    label.delete(presIntBosLb)
                int mid = math.round(math.avg(intLo.bIdx, bar_index))
                presIntBosLn := line.new(intLo.bIdx, intLo.level, bar_index, intLo.level, xloc=xloc.bar_index, color=intBearCol, style=line.style_dashed)
                presIntBosLb := label.new(mid, intLo.level, "BOS", xloc=xloc.bar_index, color=color(na), textcolor=intBearCol, style=label.style_label_down, size=getSize(intLblSz))
            if not na(intHi.level)
                if not na(intCorr.ln)
                    line.delete(intCorr.ln)
                float imp       = intHi.level - intLo.level
                intCorr.level   := intLo.level + corrFactor * imp
                intCorr.startIdx := bar_index
                intCorr.dir     := BEAR
                intCorr.active  := true
                if inRange
                    intCorr.ln := line.new(bar_index, intCorr.level, bar_index + 1, intCorr.level, xloc=xloc.bar_index, color=corrBearCol, width=corrLnWidth, style=getStyle(corrLnStyle), extend=extend.right)
            if intTr == 0
                intTr := BEAR

if showSwing
    if ta.crossover(close, swgHi.level) and not swgHi.crossed
        swgHi.crossed := true
        if swgTr == BULL or swgTr == 0
            aSwgBullBos := true
            bool showBos = showSwgBull == "All" or showSwgBull == "BOS"
            if showBos and inRange
                if modeInput == "Present"
                    line.delete(presSwgBosLn)
                    label.delete(presSwgBosLb)
                int mid = math.round(math.avg(swgHi.bIdx, bar_index))
                presSwgBosLn := line.new(swgHi.bIdx, swgHi.level, bar_index, swgHi.level, xloc=xloc.bar_index, color=swgBullCol, style=line.style_solid)
                presSwgBosLb := label.new(mid, swgHi.level, "BOS", xloc=xloc.bar_index, color=color(na), textcolor=swgBullCol, style=label.style_label_down, size=getSize(swgLblSz))
            if not na(swgLo.level)
                if not na(swgCorr.ln)
                    line.delete(swgCorr.ln)
                float imp        = swgHi.level - swgLo.level
                swgCorr.level    := swgHi.level - corrFactor * imp
                swgCorr.startIdx := bar_index
                swgCorr.dir      := BULL
                swgCorr.active   := true
                if inRange
                    swgCorr.ln := line.new(bar_index, swgCorr.level, bar_index + 1, swgCorr.level, xloc=xloc.bar_index, color=corrBullCol, width=corrLnWidth, style=getStyle(corrLnStyle), extend=extend.right)
            if swgTr == 0
                swgTr := BULL

    if ta.crossunder(close, swgLo.level) and not swgLo.crossed
        swgLo.crossed := true
        if swgTr == BEAR or swgTr == 0
            aSwgBearBos := true
            bool showBos = showSwgBear == "All" or showSwgBear == "BOS"
            if showBos and inRange
                if modeInput == "Present"
                    line.delete(presSwgBosLn)
                    label.delete(presSwgBosLb)
                int mid = math.round(math.avg(swgLo.bIdx, bar_index))
                presSwgBosLn := line.new(swgLo.bIdx, swgLo.level, bar_index, swgLo.level, xloc=xloc.bar_index, color=swgBearCol, style=line.style_solid)
                presSwgBosLb := label.new(mid, swgLo.level, "BOS", xloc=xloc.bar_index, color=color(na), textcolor=swgBearCol, style=label.style_label_up, size=getSize(swgLblSz))
            if not na(swgHi.level)
                if not na(swgCorr.ln)
                    line.delete(swgCorr.ln)
                float imp        = swgHi.level - swgLo.level
                swgCorr.level    := swgLo.level + corrFactor * imp
                swgCorr.startIdx := bar_index
                swgCorr.dir      := BEAR
                swgCorr.active   := true
                if inRange
                    swgCorr.ln := line.new(bar_index, swgCorr.level, bar_index + 1, swgCorr.level, xloc=xloc.bar_index, color=corrBearCol, width=corrLnWidth, style=getStyle(corrLnStyle), extend=extend.right)
            if swgTr == 0
                swgTr := BEAR

if showInternal and intCorr.active and not na(intCorr.level)
    if intCorr.dir == BEAR and intTr == BEAR
        bool crossed = (close > intCorr.level and close[1] <= intCorr.level) or (close > intCorr.level and open <= intCorr.level)
        if crossed
            aIntBullCh := true
            bool showCh = showIntBull == "All" or showIntBull == "CHoCH"
            if showCh and inRange
                if not na(intCorr.ln)
                    line.delete(intCorr.ln)
                if modeInput == "Present"
                    line.delete(presIntChLn)
                    label.delete(presIntChLb)
                int st  = nz(intCorr.startIdx, bar_index - 10)
                int mid = math.round(math.avg(st, bar_index))
                presIntChLn := line.new(st, intCorr.level, bar_index, intCorr.level, xloc=xloc.bar_index, color=intBullCol, style=line.style_dotted)
                presIntChLb := label.new(mid, intCorr.level, "CHoCH", xloc=xloc.bar_index, color=color(na), textcolor=intBullCol, style=label.style_label_up, size=getSize(intLblSz))
            else if not na(intCorr.ln)
                line.delete(intCorr.ln)
            intCorr.active := false
            intCorr.ln     := na
            intTr          := BULL

    if intCorr.active and intCorr.dir == BULL and intTr == BULL
        bool crossed = (close < intCorr.level and close[1] >= intCorr.level) or (close < intCorr.level and open >= intCorr.level)
        if crossed
            aIntBearCh := true
            bool showCh = showIntBear == "All" or showIntBear == "CHoCH"
            if showCh and inRange
                if not na(intCorr.ln)
                    line.delete(intCorr.ln)
                if modeInput == "Present"
                    line.delete(presIntChLn)
                    label.delete(presIntChLb)
                int st  = nz(intCorr.startIdx, bar_index - 10)
                int mid = math.round(math.avg(st, bar_index))
                presIntChLn := line.new(st, intCorr.level, bar_index, intCorr.level, xloc=xloc.bar_index, color=intBearCol, style=line.style_dotted)
                presIntChLb := label.new(mid, intCorr.level, "CHoCH", xloc=xloc.bar_index, color=color(na), textcolor=intBearCol, style=label.style_label_down, size=getSize(intLblSz))
            else if not na(intCorr.ln)
                line.delete(intCorr.ln)
            intCorr.active := false
            intCorr.ln     := na
            intTr          := BEAR

if showSwing and swgCorr.active and not na(swgCorr.level)
    if swgCorr.dir == BEAR and swgTr == BEAR
        bool crossed = (close > swgCorr.level and close[1] <= swgCorr.level) or (close > swgCorr.level and open <= swgCorr.level)
        if crossed
            aSwgBullCh := true
            bool showCh = showSwgBull == "All" or showSwgBull == "CHoCH"
            if showCh and inRange
                if not na(swgCorr.ln)
                    line.delete(swgCorr.ln)
                if modeInput == "Present"
                    line.delete(presSwgChLn)
                    label.delete(presSwgChLb)
                int st  = nz(swgCorr.startIdx, bar_index - 10)
                int mid = math.round(math.avg(st, bar_index))
                presSwgChLn := line.new(st, swgCorr.level, bar_index, swgCorr.level, xloc=xloc.bar_index, color=swgBullCol, width=2, style=line.style_dotted)
                presSwgChLb := label.new(mid, swgCorr.level, "CHoCH", xloc=xloc.bar_index, color=color(na), textcolor=swgBullCol, style=label.style_label_up, size=getSize(swgLblSz))
            else if not na(swgCorr.ln)
                line.delete(swgCorr.ln)
            swgCorr.active := false
            swgCorr.ln     := na
            swgTr          := BULL

    if swgCorr.active and swgCorr.dir == BULL and swgTr == BULL
        bool crossed = (close < swgCorr.level and close[1] >= swgCorr.level) or (close < swgCorr.level and open >= swgCorr.level)
        if crossed
            aSwgBearCh := true
            bool showCh = showSwgBear == "All" or showSwgBear == "CHoCH"
            if showCh and inRange
                if not na(swgCorr.ln)
                    line.delete(swgCorr.ln)
                if modeInput == "Present"
                    line.delete(presSwgChLn)
                    label.delete(presSwgChLb)
                int st  = nz(swgCorr.startIdx, bar_index - 10)
                int mid = math.round(math.avg(st, bar_index))
                presSwgChLn := line.new(st, swgCorr.level, bar_index, swgCorr.level, xloc=xloc.bar_index, color=swgBearCol, width=2, style=line.style_dotted)
                presSwgChLb := label.new(mid, swgCorr.level, "CHoCH", xloc=xloc.bar_index, color=color(na), textcolor=swgBearCol, style=label.style_label_down, size=getSize(swgLblSz))
            else if not na(swgCorr.ln)
                line.delete(swgCorr.ln)
            swgCorr.active := false
            swgCorr.ln     := na
            swgTr          := BEAR

if showHLSwings
    trail.top     := math.max(high, nz(trail.top, high))
    trail.topTime := trail.top == high ? time : trail.topTime
    trail.bot     := math.min(low, nz(trail.bot, low))
    trail.botTime := trail.bot == low ? time : trail.botTime
    var line  hlTopLn  = line.new(na, na, na, na, xloc=xloc.bar_time, color=swgBearCol)
    var line  hlBotLn  = line.new(na, na, na, na, xloc=xloc.bar_time, color=swgBullCol)
    var label hlTopLbl = label.new(na, na, xloc=xloc.bar_time, color=color(na), textcolor=swgBearCol, style=label.style_label_down, size=size.tiny)
    var label hlBotLbl = label.new(na, na, xloc=xloc.bar_time, color=color(na), textcolor=swgBullCol, style=label.style_label_up, size=size.tiny)
    int rightT = last_bar_time + 20 * (time - time[1])
    hlTopLn.set_first_point(chart.point.new(trail.topTime, na, trail.top))
    hlTopLn.set_second_point(chart.point.new(rightT, na, trail.top))
    hlTopLbl.set_point(chart.point.new(rightT, na, trail.top))
    hlTopLbl.set_text(swgTr == BEAR ? "Strong High" : "Weak High")
    hlBotLn.set_first_point(chart.point.new(trail.botTime, na, trail.bot))
    hlBotLn.set_second_point(chart.point.new(rightT, na, trail.bot))
    hlBotLbl.set_point(chart.point.new(rightT, na, trail.bot))
    hlBotLbl.set_text(swgTr == BULL ? "Strong Low" : "Weak Low")

color cCol = intTr == BULL ? swgBullCol : swgBearCol
plotcandle(showTrend ? open : na, high, low, close, color=cCol, wickcolor=cCol, bordercolor=cCol)
bgcolor(showTrend and swgTr == BULL ? color.new(swgBullCol, 95) : showTrend and swgTr == BEAR ? color.new(swgBearCol, 95) : na)

alertcondition(aIntBullBos,  "Internal Bullish BOS",   "Internal Bullish BOS")
alertcondition(aIntBearBos,  "Internal Bearish BOS",   "Internal Bearish BOS")
alertcondition(aIntBullCh,   "Internal Bullish CHoCH",  "Internal Bullish CHoCH")
alertcondition(aIntBearCh,   "Internal Bearish CHoCH",  "Internal Bearish CHoCH")
alertcondition(aSwgBullBos,  "Swing Bullish BOS",       "Swing Bullish BOS")
alertcondition(aSwgBearBos,  "Swing Bearish BOS",       "Swing Bearish BOS")
alertcondition(aSwgBullCh,   "Swing Bullish CHoCH",     "Swing Bullish CHoCH")
alertcondition(aSwgBearCh,   "Swing Bearish CHoCH",     "Swing Bearish CHoCH")
alertcondition(aIntBullBos or aIntBearBos or aSwgBullBos or aSwgBearBos or aIntBullCh or aIntBearCh or aSwgBullCh or aSwgBearCh, "Any Signal", "Structure signal detected")

Overview

BOS & CHoCH [AFTHAB] labels break of structure and change of character. After a break of structure, a change of character appears only when price retraces beyond a Fibonacci correction of the impulse, default 0.382. Users can filter bullish or bearish labels, apply a confluence filter, show strong and weak highs and lows, color candles by internal trend, and switch between historical and present modes. It does not place trades.

Details

Published by

kvmafthab-pixel on GitHub

Code credit

AFTHAB, as written in the script's header

Type

Indicator, Pine Script v6

Draws

On the price chart

Category

SMC / ICT / price action

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.

Topics

pinescript-tradingview-trading-xauusdtechnical-analysis-smart-money

Settings

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

SettingTypeDefaultVariable
ModestringHistoricalmodeInput
Color Candles by TrendboolfalseshowTrend
Max Historical Barsint400maxBars
Show Internal StructurebooltrueshowInternal
BullishstringAllshowIntBull
intBullColcolor#089981intBullCol
BearishstringAllshowIntBear
intBearColcolor#f23645intBearCol
Confluence FilterboolfalseintConfluence
Label SizestringTinyintLblSz
Show Swing StructurebooltrueshowSwing
BullishstringAllshowSwgBull
Show all 24 settings
SettingTypeDefaultVariable
swgBullColcolor#089981swgBullCol
BearishstringAllshowSwgBear
swgBearColcolor#f23645swgBearCol
Label SizestringSmallswgLblSz
Show Swing PointsboolfalseshowSwgPts
swgLengthint50swgLength
Show Strong/Weak High/LowbooltrueshowHLSwings
Correction Level (Fib)float0.382corrFactor
Correction Line StylestringDashedcorrLnStyle
Correction Line Widthint1corrLnWidth
Bull Correctioncolorcolor.new(#089981, 40)corrBullCol
Bear Correctioncolorcolor.new(#f23645, 40)corrBearCol
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

575 stars

The indicator plots ICT displacement candles on the price chart and can switch to retracement scanning. Displacement requires a move larger than a set share of the 14-bar average high-low range, lasting at least a chosen number of bars, with optional close, pr

Indicator v6 SMC / ICT / price actionCandlestick patterns
Updated 1 year ago · MPL-2.0 GitHub repository of ICT Displacement Candles Indicator

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

Fair Value Gaps - Basic

by TradersPost
218 stars

This indicator detects bullish and bearish fair value gaps on the price chart and draws a translucent box for each gap. A bullish gap needs the high two bars back below the current low and a bullish middle candle; a bearish gap uses the opposite gap and a bear

Indicator v6 SMC / ICT / price action
Updated 3 months ago · None stated GitHub repository of Fair Value Gaps - Basic

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