Market Structure Indicator: BOS, CHoCH and Swing Labels

Written by Dominic Walsh · Published · Last updated

A market structure indicator should answer one question. Does the sequence of highs and lows still point the same way? This build finds swing pivots through a ZigZag scan and labels each one HH, LH, HL or LL. It then splits breaks into two kinds. A break of structure continues the existing sequence. A change of character breaks it, and only that second case earns an arrow.

This build ships as a compiled .ex4 for MT4 and .ex5 for MT5; the screenshots below come from EURUSD H1.

Platforms MT4 (.ex4) + MT5 (.ex5)
Chart window Main price chart
Plots 3: ZigZag, BUY CHoCH, SELL CHoCH
Alerts popup, push notification, email, sound
Inputs 18

What the Market Structure Indicator draws on the chart

ZigZag connects confirmed pivots with a dodger blue section line, giving the skeleton of the structure.

BUY CHoCH shows a lime arrow below the bar that closes beyond the most recent opposite pivot.

SELL CHoCH shows the red equivalent above the bar.

Text objects put HH, LH, HL and LL beside each confirmed pivot.

Rectangles mark demand and supply zones at break points, and the code flags equal highs or lows as liquidity pools.

  • ZigZag: section, dodger blue, width 2
  • BUY CHoCH: arrow, lime, width 2, arrow code 233
  • SELL CHoCH: arrow, red, width 2, arrow code 234
Market structure indicator on EURUSD H1 with the ZigZag skeleton and CHoCH arrows
Market structure indicator on EURUSD H1 with the ZigZag skeleton and CHoCH arrows

How the Market Structure Indicator calculates its values

Confirming a pivot

A bar becomes a swing high only when no bar within the scan window on either side matches or beats its high. The code sets isHigh true, then walks outward, comparing high[olderIdx] and high[newerIdx] against hi. The first violation clears the flag. Swing lows run the mirror test. Because the code must check both sides, it can only confirm a pivot some bars after it printed.

Naming the sequence

The code compares each confirmed pivot with the previous pivot of the same kind. A high above the last high becomes an HH, below it an LH. A low above the last low becomes an HL, below it an LL. `ShowLabels` writes these onto the chart. HH with HL describes an uptrend sequence, LH with LL a downtrend.

Separating BOS from CHoCH

A close beyond the prior same-direction pivot signals a break of structure, which continues the trend and earns no arrow. A close beyond the most recent opposite-direction pivot signals a change of character, the reversal event. The code writes BuyArrow at low[i] minus offset, where offset converts `ArrowOffsetPts` to price. It groups equal highs and lows that fall within `EqualTolerancePts` of one another and marks them as liquidity.

How to read the signals

Read the labels as a sequence rather than one at a time. HH then HL stays intact. HH then LL does not.

No arrow on a break means the tool read that break as continuation.

An arrow says price closed through the most recent opposite pivot, the earliest structural sign of a turn.

Liquidity marks sit where several highs or lows stopped at nearly the same price.

Alert channels in this build: popup, push notification, email and sound, one message per closed bar.

Four channels appear here: popup, push notification, email and sound, each with its own switch beneath `EnableAlerts`. Popup starts enabled and the others start off. The bar guard releases at most one message per closed bar however many channels you turn on.

Every Market Structure Indicator input

Core settings

Setting What it does Default
StructureLookback Bars used to confirm swing pivots. Bars the code uses to confirm a swing pivot, default `50`. Larger values yield fewer, more meaningful pivots. 50
Depth ZigZag depth (min bars between pivots). Minimum bars between ZigZag pivots, default `12`. This controls how much detail the skeleton keeps. 12
Deviation ZigZag deviation in points. Minimum swing size in points, default `5`, filtering pivots too shallow to matter. 5
EqualTolerancePts Tolerance for equal H/L grouping (points). How close two highs must sit to count as equal, default `30` points. Widen it on instruments with larger spreads. 30

Display settings

Setting What it does Default
ShowLabels Show HH/LH/HL/LL text on chart. on
ShowOrderBlocks Draw demand/supply zones on BOS/CHoCH. Draws the demand and supply rectangles at break points. Set it `false` for a plainer chart. on
ShowLiquidity Mark equal highs/lows liquidity pools. on
ColorBull (see inputs panel) lime
ColorBear (see inputs panel) red
ColorOB_Bull (see inputs panel) dark green
ColorOB_Bear (see inputs panel) maroon
ArrowOffsetPts Arrow distance from bar (points). 30

Alert settings

Setting What it does Default
EnableAlerts (see inputs panel) on
EnablePopup (see inputs panel) on
EnablePushNotify (see inputs panel) off
EnableEmail (see inputs panel) off
EnableSound (see inputs panel) off
SoundFile (see inputs panel) alert.wav
Market structure indicator inputs showing Depth, Deviation and EqualTolerancePts
Market structure indicator inputs showing Depth, Deviation and EqualTolerancePts

Settings that fit your chart

Structure reading suits liquid instruments with clean swings, and the reference capture uses EURUSD on H1. The `Depth` of `12` and `Deviation` of `5` fit that kind of chart. On M1 those same values produce pivots every few bars and the labels crowd together. On the daily chart pivots grow rare enough that you may want a lower `Depth` to see intermediate structure.

When the Market Structure Indicator fails

Pivot confirmation needs bars on both sides, so the ZigZag skeleton finalises late. The newest leg can still change while it forms.

A tight range alternates between HH and LL without any real trend, and the tool then prints change of character arrows in both directions.

Equal high and low grouping uses a fixed point tolerance, so one `EqualTolerancePts` value runs too tight on gold and too loose on a calm pair.

Copy the compiled Market Structure Indicator file into your MQL4/Indicators folder, and the MT5 build into MQL5/Indicators, then restart the terminal and drag it onto a chart. The step-by-step guide with screenshots is at how to install MT4 and MT5 indicators.

Background reading on the method behind the Market Structure Indicator: Naive diversification on Wikipedia, Asset Allocation And Diversification at StockCharts ChartSchool.

Download the Market Structure Indicator for MT4 and MT5

The zip holds the compiled Market Structure Indicator build for MT4 and MT5, plus a short README. Compiled files only, no source. Enter your email below and the download link arrives in your inbox.

Download this indicator free

Enter your email and the file is yours. You also get the full MT4 and MT5 library.

  • 1,380+ indicators
  • MT4 and MT5 files
  • No spam, unsubscribe any time

FAQ

What separates a BOS from a BUY CHoCH in this code?

The reference pivot. A break of structure closes beyond the last pivot pointing the same way as the current trend, so it extends the sequence. A change of character closes beyond the most recent pivot pointing the other way, which breaks the sequence. Only that second case prints a BUY CHoCH or SELL CHoCH arrow.

Why does StructureLookback make pivot labels appear late?

A pivot cannot confirm until the bars after it exist. The test needs no bar on either side within the scan window to beat the candidate high or low. Until those later bars print, the code cannot know whether the candidate survives, so labels always trail the actual turn by several bars.

How should I set Depth on a fast timeframe?

Raise it. `Depth` sets the minimum bars between pivots and defaults to `12`. On M5 or M1 that allows a pivot every twelve bars, which produces far more structure than you can use. Twenty to forty keeps the skeleton readable. On daily charts you may want to lower it instead.

What does EqualTolerancePts count as equal highs?

Two or more highs within `30` points of each other by default. The code groups them rather than demanding an exact match, since exact ties happen rarely. Those clusters mark where resting orders tend to sit, which is why the tool flags them separately from ordinary pivots.

Are results guaranteed?

No. Trading involves risk. Results are not guaranteed; past performance is not indicative of future results. Use the Market Structure Indicator as one input. Always backtest before trading live.

Category: this is part of our Smart Money collection. Browse more Smart Money for MetaTrader, or explore every MT4 indicator and MT5 indicator on the site.

External references

Dominic Walsh - Forex trader and MT4/MT5 developer

About the author

Written by Dominic Walsh, a Forex trader and MT4/MT5 indicator, Expert Advisor and script developer. Every tool on forexmt4systems.com is tested on live charts before release and ships with ready-to-use compiled MT4 (.ex4) and MT5 (.ex5) files. Learn more about the trader and developer behind this site.

How we build, test and correct every tool: Editorial & Testing Policy. Trading carries risk; see the disclaimer.

Leave a Comment