Home / Free Gold Indicator

Gold Structure Lite: a Free TradingView Indicator for Gold

Pine Script v5 · MPL-2.0 licence · Version 1.0, October 18, 2026 · by XAUUSDLiveChart.com

Gold Structure Lite puts the structure layer of the XAUUSD live chart on a TradingView chart: the 50 and 200 EMA for context, an ATR band for stop distance, confirmed swing highs and lows, and BOS and CHoCH labels that are only drawn on a closed candle. It is free, it never repaints, and it gives no signals.

What it draws

EMA 50 and EMA 200The trend filter. Fast above slow is bullish context, fast below slow is bearish context. The status box in the corner states which one is active.
ATR stop bandA band around the fast EMA, one and a half ATR wide by default. It is a distance reference for stops, not an entry signal. Tinted green or red by the EMA context.
Swing H and LConfirmed pivot highs and lows, five bars either side by default. They appear five bars late on purpose, so they never move once printed.
BOS and CHoCHBOS when a candle closes beyond the last swing in the direction of the current structure. CHoCH when the close breaks the swing against it. Labels are created on confirmed closes only.

How to install it

  1. Open any chart on TradingView and click Pine Editor at the bottom of the screen.
  2. Delete the sample code, press Copy code below and paste the script into the editor.
  3. Click Add to chart. The EMAs, the band and the labels appear on the current symbol and timeframe.
  4. Optional: click Save to keep it in your indicators list, and set alerts on "Bullish structure break" or "Bearish structure break".

The same code can be opened from the TradingView indicator library under the name Gold Structure Lite once the public listing is live. Either route gives you the same script.

gold-structure-lite.pine · Pine Script v5Download .pine
// This Pine Script code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// Gold Structure Lite  -  free structure indicator for XAUUSD and other markets
// Published by XAUUSD Live Chart  -  https://xauusdlivechart.com
// How to read it: https://xauusdlivechart.com/free-gold-indicator
//
// What it draws
//   1. EMA 50 and EMA 200 (trend filter: 50 above 200 = bullish context, below = bearish)
//   2. An ATR stop band around the EMA 50 (a volatility-sized distance for stops, not a signal)
//   3. Swing highs and lows found with confirmed pivots, and the structure labels built from them:
//        BOS   = Break of Structure   : close beyond the last swing in the direction of the current trend
//        CHoCH = Change of Character  : close beyond the last swing AGAINST the current trend
//
// No repaint rules
//   - Pivots only exist after `pivotRight` bars have closed to the right of them, so a swing is never
//     redrawn once it is printed. The cost is a delay of `pivotRight` bars, which is deliberate.
//   - Every BOS / CHoCH label is created on a CONFIRMED bar close (barstate.isconfirmed), never on a
//     forming candle. A wick through a level does not count; only a close does.
//   - Nothing uses future data (no lookahead, no security() calls).
//
// It is a reading aid. It does not give buy or sell signals and it is not financial advice.

//@version=5
indicator("Gold Structure Lite", shorttitle="GS Lite", overlay=true, max_labels_count=200, max_lines_count=200)

// ---------- inputs ----------
grpT = "Trend"
emaFastLen = input.int(50,  "Fast EMA",  minval=2,  group=grpT)
emaSlowLen = input.int(200, "Slow EMA",  minval=2,  group=grpT)
showEma    = input.bool(true, "Show EMAs", group=grpT)

grpA = "ATR stop band"
atrLen  = input.int(14,   "ATR length",      minval=1,   group=grpA)
atrMult = input.float(1.5, "ATR multiplier", minval=0.1, step=0.1, group=grpA)
showBand = input.bool(true, "Show ATR band around the fast EMA", group=grpA)

grpS = "Structure"
pivotLeft  = input.int(5, "Pivot bars (left)",  minval=1, group=grpS)
pivotRight = input.int(5, "Pivot bars (right, confirmation delay)", minval=1, group=grpS)
showSwings = input.bool(true, "Mark swing highs and lows", group=grpS)
showLevels = input.bool(true, "Draw the live swing levels", group=grpS)
showLabels = input.bool(true, "BOS / CHoCH labels", group=grpS)

// ---------- trend + volatility ----------
emaFast = ta.ema(close, emaFastLen)
emaSlow = ta.ema(close, emaSlowLen)
atrVal  = ta.atr(atrLen)
bandUp  = emaFast + atrVal * atrMult
bandDn  = emaFast - atrVal * atrMult
bullCtx = emaFast > emaSlow

pFast = plot(showEma ? emaFast : na, "EMA fast", color=color.new(#f5c93a, 0), linewidth=2)
pSlow = plot(showEma ? emaSlow : na, "EMA slow", color=color.new(#8aa0b8, 0), linewidth=2)
pUp   = plot(showBand ? bandUp : na, "ATR band upper", color=color.new(#2ee6a0, 70), linewidth=1)
pDn   = plot(showBand ? bandDn : na, "ATR band lower", color=color.new(#ff5c7a, 70), linewidth=1)
fill(pUp, pDn, color=color.new(bullCtx ? #2ee6a0 : #ff5c7a, 92), title="ATR band fill")

// ---------- confirmed pivots (no repaint: a pivot appears only after pivotRight closed bars) ----------
ph = ta.pivothigh(high, pivotLeft, pivotRight)   // value of the swing high, printed pivotRight bars late
pl = ta.pivotlow(low,  pivotLeft, pivotRight)

var float lastHigh = na          // most recent confirmed swing high (price)
var float lastLow  = na          // most recent confirmed swing low  (price)
var int   lastHighBar = na
var int   lastLowBar  = na
var int   trendDir = 0           // +1 after a bullish break, -1 after a bearish break, 0 until the first break
var bool  highTaken = false      // the current swing high has already been broken by a close
var bool  lowTaken  = false

if not na(ph)
    lastHigh := ph
    lastHighBar := bar_index - pivotRight
    highTaken := false
    if showSwings
        label.new(lastHighBar, lastHigh, "H", style=label.style_label_down, color=color.new(#ff5c7a, 60), textcolor=color.white, size=size.tiny)
if not na(pl)
    lastLow := pl
    lastLowBar := bar_index - pivotRight
    lowTaken := false
    if showSwings
        label.new(lastLowBar, lastLow, "L", style=label.style_label_up, color=color.new(#2ee6a0, 60), textcolor=color.white, size=size.tiny)

// ---------- live swing levels (one line per side, extended to the current bar) ----------
var line hiLine = na
var line loLine = na
if showLevels and not na(lastHigh)
    if na(hiLine)
        hiLine := line.new(lastHighBar, lastHigh, bar_index, lastHigh, color=color.new(#ff5c7a, 30), style=line.style_dotted)
    else
        line.set_xy1(hiLine, lastHighBar, lastHigh)
        line.set_xy2(hiLine, bar_index, lastHigh)
if showLevels and not na(lastLow)
    if na(loLine)
        loLine := line.new(lastLowBar, lastLow, bar_index, lastLow, color=color.new(#2ee6a0, 30), style=line.style_dotted)
    else
        line.set_xy1(loLine, lastLowBar, lastLow)
        line.set_xy2(loLine, bar_index, lastLow)

// ---------- structure breaks, decided on CONFIRMED closes only ----------
// Bullish break: a close above the last swing high that has not been taken yet.
// Bearish break: a close below the last swing low that has not been taken yet.
// BOS when the break continues the current trend, CHoCH when it reverses it (or when there is no trend yet).
bullBreak = barstate.isconfirmed and not na(lastHigh) and not highTaken and close > lastHigh
bearBreak = barstate.isconfirmed and not na(lastLow)  and not lowTaken  and close < lastLow

if bullBreak
    isChoch = trendDir <= 0
    if showLabels
        label.new(bar_index, lastHigh, isChoch ? "CHoCH" : "BOS", style=label.style_label_down, color=color.new(#2ee6a0, isChoch ? 0 : 35), textcolor=#04100b, size=size.small, tooltip=(isChoch ? "Change of character: " : "Break of structure: ") + "close above the swing high " + str.tostring(lastHigh, format.mintick))
    highTaken := true
    trendDir := 1
if bearBreak
    isChoch = trendDir >= 0
    if showLabels
        label.new(bar_index, lastLow, isChoch ? "CHoCH" : "BOS", style=label.style_label_up, color=color.new(#ff5c7a, isChoch ? 0 : 35), textcolor=color.white, size=size.small, tooltip=(isChoch ? "Change of character: " : "Break of structure: ") + "close below the swing low " + str.tostring(lastLow, format.mintick))
    lowTaken := true
    trendDir := -1

// ---------- alerts (fire once per confirmed bar) ----------
alertcondition(bullBreak, "Bullish structure break", "Gold Structure Lite: close above the last swing high")
alertcondition(bearBreak, "Bearish structure break", "Gold Structure Lite: close below the last swing low")

// ---------- small status box ----------
var table info = table.new(position.top_right, 1, 3, border_width=0)
if barstate.islast
    table.cell(info, 0, 0, "Gold Structure Lite", text_color=#8aa0b8, text_size=size.tiny)
    table.cell(info, 0, 1, (bullCtx ? "EMA context: bullish" : "EMA context: bearish"), text_color=(bullCtx ? #2ee6a0 : #ff5c7a), text_size=size.small)
    table.cell(info, 0, 2, trendDir > 0 ? "Structure: bullish (last break up)" : trendDir < 0 ? "Structure: bearish (last break down)" : "Structure: no break yet", text_color=#e6edf3, text_size=size.small)

Licence: Mozilla Public License 2.0. You may use, modify and republish the code; keep the licence header.

How to read it on gold

Start with the status box. If the EMA context says bullish and the last structure break was up, you are looking for pullbacks into demand, not for shorts. If the two disagree, the market is transitioning and the honest reading is to wait for the next label.

A BOS label confirms that the trend has made a new leg. The swing it broke becomes the level to watch on a pullback. A CHoCH label is the first warning that the sequence has flipped. One CHoCH does not make a new trend, and gold produces false flips around news, so treat it as a reason to stop pressing the old direction rather than a reason to reverse.

The ATR band answers one question: how much normal movement should a stop survive. A stop inside the band is likely to be hit by noise. The methodology behind this, and why gold needs volatility-sized stops, is covered in the ATR stop-loss guide and the best indicator for gold page.

Settings worth changing

Three ways a label can mislead you

First, a CHoCH printed in the middle of a range is not a reversal; it is the range doing what ranges do. Check the EMA context and the higher timeframe before reading anything into it. Second, a BOS that forms on a news candle can be undone within the hour, because the close that confirmed it was a spike, not a decision. Wait for the next candle. Third, a swing label that appears five bars late can tempt you to act on the level as if it were fresh. It is not fresh; price has already moved on, and the useful question is whether it returns to that level, not whether it broke it. Reading the labels with those three cautions in mind is the difference between a structure map and a signal generator.

What it does not do

It does not draw supply and demand zones or order blocks; the live chart on this site does that with scoring and lifecycle rules that are documented on the methodology page. It does not use volume, because spot gold on most TradingView feeds shows tick volume. It does not predict. A label describes a closed candle, nothing more. Learn the concepts behind the labels in the free SMC course, then decide with your own plan and risk rules. This page is educational and is not investment advice.

FAQ

Is Gold Structure Lite free?

Yes. The code is published under the Mozilla Public License 2.0. Copy it into the TradingView Pine Editor, or open it from the TradingView indicator library once it is listed there. There is no paid version.

Does the indicator repaint?

No. Swing points are confirmed pivots, so they only appear after the chosen number of bars has closed to the right, and BOS and CHoCH labels are created on a confirmed candle close. The price for that is a delay of a few bars, which is deliberate.

Does it work on markets other than gold?

Yes. The logic is generic market structure with EMA and ATR context, so it runs on any symbol and timeframe. The defaults were chosen with gold in mind, which is why the ATR band is wide.

Is there an MT5 version?

Not yet. The structure layer is available on the live chart on this site without any installation, and the Pine Script version covers TradingView. An MT5 port is on the list but has no date.

Is this a trading signal?

No. The labels describe what price has done on closed candles. They do not tell you to buy or sell, and the site does not provide investment advice.

Prefer zones and order blocks drawn for you? Open the live gold chart, no installation needed.

← Back to home

Join Group
×Gold price ya broker ke baare mein poochho — ask in English or Urdu.