Indicator · Pine Script v5 · On the chart

Breaker Blocks

by nexobanks-prep

A smart money indicator that finds swing highs and lows with a pivot length, detects a break of structure, and marks the last opposing candle before it as an order block.

View on GitHub

GitHub stars1on the repository
Pine versionv5runs as is
Lines of code355
Settings11inputs
LicenceNone statedfile: MPL-2.0
Last update7 months ago12 Mar 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

355 lines of Pine Script v5 from pinescripts/breaker_blocks.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

breaker_blocks.pine
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0
// https://mozilla.org/MPL/2.0/
//
// © nexobanks-prep / HFT-Bot – open-source, free to use and modify.
//
// ─────────────────────────────────────────────────────────────────────────────
//  BREAKER BLOCKS  (Smart Money Concepts)
//  TradingView Pine Script v5
// ─────────────────────────────────────────────────────────────────────────────
//
//  What is a Breaker Block?
//  ─────────────────────────
//  A Breaker Block is a *failed* Order Block.
//
//  • Order Block (OB): the last opposing candle before a strong impulsive move
//    that also takes out a prior swing high/low (a "Break of Structure").
//
//  • When price later returns and breaks *through* that Order Block zone,
//    the zone "flips":
//      – A bullish OB that gets broken to the downside → Bearish Breaker Block
//        (former support now acts as resistance)
//      – A bearish OB that gets broken to the upside  → Bullish Breaker Block
//        (former resistance now acts as support)
//
//  Detection logic (this script)
//  ─────────────────────────────
//  1.  Find swing highs / swing lows using a configurable pivot length.
//  2.  Detect Break-of-Structure (BOS):
//        • Bullish BOS  – close > prior swing high  → look back for last
//          bearish (down-close) candle before the BOS candle as the OB zone.
//        • Bearish BOS  – close < prior swing low   → look back for last
//          bullish (up-close) candle before the BOS candle as the OB zone.
//  3.  Mark each OB zone.  When price later closes *through* the OB zone
//      in the opposite direction it becomes a Breaker Block.
//  4.  Draw filled boxes for active Breaker Blocks; extend them until price
//      revisits (mitigates) the zone.
//
// ─────────────────────────────────────────────────────────────────────────────
//  BOS direction → Order Block type → Breaker Block type (quick reference)
//  ─────────────────────────────────────────────────────────────────────────
//  Bullish BOS (close crosses above swing high):
//    → last BEARISH candle before BOS = bearish Order Block
//    → when price later closes BELOW the OB bottom → BEARISH Breaker Block
//    → guarded by the "Show Bearish Breaker Blocks" toggle
//
//  Bearish BOS (close crosses below swing low):
//    → last BULLISH candle before BOS = bullish Order Block
//    → when price later closes ABOVE the OB top  → BULLISH Breaker Block
//    → guarded by the "Show Bullish Breaker Blocks" toggle
// ─────────────────────────────────────────────────────────────────────────────

//@version=5
indicator(
     title       = "Breaker Blocks [HFT-Bot]",
     shorttitle  = "BreakerBlocks",
     overlay     = true,
     max_boxes_count  = 500,
     max_lines_count  = 200,
     max_labels_count = 200
 )

// ═══════════════════════════════════════════════════════════════════════════════
// INPUTS
// ═══════════════════════════════════════════════════════════════════════════════

var string GRP_DETECTION = "Detection"
pivotLen = input.int(
     defval  = 10,
     title   = "Pivot Length",
     minval  = 2,
     maxval  = 50,
     group   = GRP_DETECTION,
     tooltip = "Number of bars on each side used to confirm a swing high/low."
 )

lookbackBars = input.int(
     defval  = 5,
     title   = "Order-Block Look-back (bars)",
     minval  = 1,
     maxval  = 20,
     group   = GRP_DETECTION,
     tooltip = "How many bars back to search for the last opposing candle that forms the Order Block."
 )

mitigationPct = input.float(
     defval  = 50.0,
     title   = "Mitigation Level (%)",
     minval  = 0.0,
     maxval  = 100.0,
     step    = 5.0,
     group   = GRP_DETECTION,
     tooltip = "A Breaker Block is considered mitigated (invalidated) when price penetrates this % of its height."
 )

var string GRP_DISPLAY = "Display"
showBullBreaker = input.bool(
     defval = true,
     title  = "Show Bullish Breaker Blocks",
     group  = GRP_DISPLAY
 )
showBearBreaker = input.bool(
     defval = true,
     title  = "Show Bearish Breaker Blocks",
     group  = GRP_DISPLAY
 )
extendBoxes = input.bool(
     defval  = true,
     title   = "Extend Boxes to the Right",
     group   = GRP_DISPLAY,
     tooltip = "Keep extending the box until the zone is mitigated."
 )
showLabels = input.bool(
     defval = true,
     title  = "Show Labels",
     group  = GRP_DISPLAY
 )

bullColor   = input.color(defval = color.new(color.teal,  70), title = "Bullish Breaker Color", group = GRP_DISPLAY)
bearColor   = input.color(defval = color.new(color.red,   70), title = "Bearish Breaker Color", group = GRP_DISPLAY)
bullBorder  = input.color(defval = color.teal,                 title = "Bullish Border Color",  group = GRP_DISPLAY)
bearBorder  = input.color(defval = color.red,                  title = "Bearish Border Color",  group = GRP_DISPLAY)

// ═══════════════════════════════════════════════════════════════════════════════
// INTERNAL STATE
// ═══════════════════════════════════════════════════════════════════════════════

// Each Breaker Block is tracked in parallel arrays so we can update (extend or
// delete) boxes on subsequent bars without needing a custom object type.
//
//  _bbTop    – top price of the zone
//  _bbBot    – bottom price of the zone
//  _bbLeft   – bar_index of the left edge
//  _bbIsBull – true = bullish breaker, false = bearish breaker
//  _bbBox    – the box drawing object
//  _bbLabel  – the label drawing object (may be na if labels off)
//  _bbDone   – true = mitigated / closed

var float[]  _bbTop    = array.new_float()
var float[]  _bbBot    = array.new_float()
var int[]    _bbLeft   = array.new_int()
var bool[]   _bbIsBull = array.new_bool()
var box[]    _bbBox    = array.new_box()
var label[]  _bbLabel  = array.new_label()
var bool[]   _bbDone   = array.new_bool()

// ═══════════════════════════════════════════════════════════════════════════════
// HELPER FUNCTIONS
// ═══════════════════════════════════════════════════════════════════════════════

// Scans backward from bar [startBar] to bar [endBar] (both are lookback offsets,
// where offset 1 = the bar immediately before the current bar).
// Returns the offset of the most-recent bearish candle found (smallest i),
// i.e. the chronologically *last* bearish candle before the current bar.
// Returns -1 if no bearish candle exists in the range.
findLastBearishCandle(int startBar, int endBar) =>
    int result = -1
    for i = startBar to endBar
        if close[i] < open[i]
            result := i
            break   // stop at the most-recent match (smallest lookback offset)
    result

// Same as above but for the most-recent bullish candle.
findLastBullishCandle(int startBar, int endBar) =>
    int result = -1
    for i = startBar to endBar
        if close[i] > open[i]
            result := i
            break
    result

// Add a new Breaker Block zone.
addBreaker(float topPrice, float botPrice, int leftBar, bool isBull) =>
    bgCol  = isBull ? bullColor  : bearColor
    bdCol  = isBull ? bullBorder : bearBorder
    lbl    = isBull ? "Bullish BB" : "Bearish BB"
    txtCol = isBull ? bullBorder  : bearBorder

    newBox = box.new(
         left         = leftBar,
         right        = bar_index,
         top          = topPrice,
         bottom       = botPrice,
         bgcolor      = bgCol,
         border_color = bdCol,
         border_width = 1
     )

    newLabel = showLabels ? label.new(
         x      = leftBar,
         y      = isBull ? botPrice : topPrice,
         text   = lbl,
         color  = color.new(color.black, 100),
         style  = isBull ? label.style_label_up : label.style_label_down,
         textcolor = txtCol,
         size   = size.small
     ) : na

    array.push(_bbTop,    topPrice)
    array.push(_bbBot,    botPrice)
    array.push(_bbLeft,   leftBar)
    array.push(_bbIsBull, isBull)
    array.push(_bbBox,    newBox)
    array.push(_bbLabel,  newLabel)
    array.push(_bbDone,   false)

// ═══════════════════════════════════════════════════════════════════════════════
// PIVOT DETECTION
// ═══════════════════════════════════════════════════════════════════════════════

// ta.pivothigh / ta.pivotlow return a value on the bar that *confirms* the pivot
// (i.e., pivotLen bars after the actual pivot bar).  The returned value is the
// price of the pivot; na if the bar is not a confirmed pivot.

swingHigh = ta.pivothigh(high, pivotLen, pivotLen)
swingLow  = ta.pivotlow (low,  pivotLen, pivotLen)

// Track the most-recent confirmed swing high / low prices and their bar indices.
var float lastSwingHigh     = na
var int   lastSwingHighBar  = na
var float lastSwingLow      = na
var int   lastSwingLowBar   = na

if not na(swingHigh)
    lastSwingHigh    := swingHigh
    lastSwingHighBar := bar_index - pivotLen   // actual pivot bar

if not na(swingLow)
    lastSwingLow    := swingLow
    lastSwingLowBar := bar_index - pivotLen

// ═══════════════════════════════════════════════════════════════════════════════
// BREAK OF STRUCTURE → ORDER BLOCK → BREAKER BLOCK
// ═══════════════════════════════════════════════════════════════════════════════

// ── Bullish BOS: current close breaks above the last confirmed swing high ──
bullBOS = not na(lastSwingHigh) and ta.crossover(close, lastSwingHigh)
// ── Bearish BOS: current close breaks below the last confirmed swing low ──
bearBOS = not na(lastSwingLow)  and ta.crossunder(close, lastSwingLow)

// When a bullish BOS fires we look back for the last *bearish* candle
// (the OB) within lookbackBars.  That zone is the potential Breaker Block if
// price later comes back and breaks through it downward.
// But per the definition the Breaker Block is only *activated* once price has
// already broken back through the OB in the opposite direction.
//
// Simplified approach used here (widely adopted in community scripts):
//   • At the moment of BOS we record the OB zone.
//   • On every subsequent bar we check whether price has closed *back through*
//     the OB zone (in the direction that would "break" it).
//   • Once broken, the OB flips to a Breaker Block and we draw it.

// Storage for pending (unbroken) order blocks.
// _obBullBreaker = true means this OB will become a BULLISH breaker once re-entered.
var float[]  _obTop         = array.new_float()
var float[]  _obBot         = array.new_float()
var int[]    _obBar         = array.new_int()
var bool[]   _obBullBreaker = array.new_bool()   // true → bullish breaker; false → bearish breaker
var bool[]   _obDone        = array.new_bool()

// ── Register new Order Blocks on Break-of-Structure ──────────────────────────
if bullBOS and showBearBreaker
    // Bullish BOS → last bearish candle = bearish OB → will become a BEARISH breaker
    obIdx = findLastBearishCandle(1, math.min(lookbackBars, bar_index))
    if obIdx >= 0
        obTop = math.max(open[obIdx], close[obIdx])
        obBot = math.min(open[obIdx], close[obIdx])
        array.push(_obTop,         obTop)
        array.push(_obBot,         obBot)
        array.push(_obBar,         bar_index - obIdx)
        array.push(_obBullBreaker, false)   // bearish OB → bearish breaker when broken below
        array.push(_obDone,        false)

if bearBOS and showBullBreaker
    // Bearish BOS → last bullish candle = bullish OB → will become a BULLISH breaker
    obIdx = findLastBullishCandle(1, math.min(lookbackBars, bar_index))
    if obIdx >= 0
        obTop = math.max(open[obIdx], close[obIdx])
        obBot = math.min(open[obIdx], close[obIdx])
        array.push(_obTop,         obTop)
        array.push(_obBot,         obBot)
        array.push(_obBar,         bar_index - obIdx)
        array.push(_obBullBreaker, true)    // bullish OB → bullish breaker when broken above
        array.push(_obDone,        false)

// ── Check whether any pending OB has been broken (→ becomes Breaker Block) ───
if array.size(_obTop) > 0
    for i = array.size(_obTop) - 1 to 0
        if not array.get(_obDone, i)
            obTop        = array.get(_obTop,         i)
            obBot        = array.get(_obBot,         i)
            obBar        = array.get(_obBar,         i)
            obBullBreaker = array.get(_obBullBreaker, i)

            // Bullish OB: price closes above the OB top → activates as BULLISH breaker
            bullBroken = obBullBreaker  and close > obTop
            // Bearish OB: price closes below the OB bottom → activates as BEARISH breaker
            bearBroken = not obBullBreaker and close < obBot

            if bullBroken or bearBroken
                addBreaker(obTop, obBot, obBar, obBullBreaker)
                array.set(_obDone, i, true)

// ═══════════════════════════════════════════════════════════════════════════════
// EXTEND ACTIVE BREAKER BLOCKS & CHECK MITIGATION
// ═══════════════════════════════════════════════════════════════════════════════

if array.size(_bbTop) > 0
    for i = array.size(_bbTop) - 1 to 0
        if not array.get(_bbDone, i)
            bbTop   = array.get(_bbTop,    i)
            bbBot   = array.get(_bbBot,    i)
            isBull  = array.get(_bbIsBull, i)
            bbBoxObj = array.get(_bbBox,   i)

            // Mitigation price
            zoneHeight   = bbTop - bbBot
            mitigLevel   = isBull
                 ? bbBot + zoneHeight * (mitigationPct / 100.0)   // bull: measured from bottom
                 : bbTop - zoneHeight * (mitigationPct / 100.0)   // bear: measured from top

            mitigated = isBull
                 ? low  <= mitigLevel   // price dips into bullish breaker zone
                 : high >= mitigLevel   // price pops into bearish breaker zone

            if mitigated
                // Close the box at the current bar and mark done
                box.set_right(bbBoxObj, bar_index)
                array.set(_bbDone, i, true)
            else if extendBoxes
                box.set_right(bbBoxObj, bar_index + 1)

// ═══════════════════════════════════════════════════════════════════════════════
// DEBUG / PIVOT MARKERS  (optional visual confirmation)
// ═══════════════════════════════════════════════════════════════════════════════

plotshape(
     series    = not na(swingHigh),
     title     = "Swing High",
     style     = shape.triangledown,
     location  = location.abovebar,
     color     = color.new(color.orange, 0),
     size      = size.tiny,
     offset    = -pivotLen
 )

plotshape(
     series    = not na(swingLow),
     title     = "Swing Low",
     style     = shape.triangleup,
     location  = location.belowbar,
     color     = color.new(color.lime, 0),
     size      = size.tiny,
     offset    = -pivotLen
 )

Overview

When price later closes through that block, the zone flips into a bullish or bearish breaker block and is drawn as a filled box on the price chart. Boxes can extend right until mitigated at a set percentage. Settings cover pivot length, order block look-back, mitigation level, labels and colours.

Details

Published by

nexobanks-prep 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 Lengthint10pivotLen
Order-Block Look-back (bars)int5lookbackBars
Mitigation Level (%)float50.0mitigationPct
Show Bullish Breaker BlocksbooltrueshowBullBreaker
Show Bearish Breaker BlocksbooltrueshowBearBreaker
Extend Boxes to the RightbooltrueextendBoxes
Show LabelsbooltrueshowLabels
Bullish Breaker Colorcolorcolor.new(color.teal, 70)bullColor
Bearish Breaker Colorcolorcolor.new(color.red, 70)bearColor
Bullish Border Colorcolorcolor.tealbullBorder
Bearish Border Colorcolorcolor.redbearBorder
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
228 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 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