A swing-mapping tool that connects significant highs and lows with straight lines — and the canonical example of an indicator that repaints by construction.
ZigZag is a chart overlay that draws straight lines between significant swing highs and swing lows, ignoring every price move smaller than a chosen threshold (a percentage, a point amount, or a pivot depth in bars). The result is a clean skeleton of the market's swing structure, which is why it is popular for labeling waves, measuring retracements, and studying chart patterns. It is essential to understand what ZigZag is not: it is not a signal generator. The most recent leg of a ZigZag is always provisional — it is redrawn as new bars arrive — so the indicator repaints by construction, not by bug. A pivot only becomes final after price has already reversed by the full threshold, which means every 'perfect' turning point you see on historical charts was identified with hindsight. ZigZag is a descriptive tool for analyzing completed structure, and any backtest that acts on its live pivots is invalid. This is educational material only, not financial advice; no indicator predicts price, and all trading carries risk of loss.
The classic percentage ZigZag works as a state machine. Starting from the last confirmed pivot, the algorithm tracks the most extreme price reached in the current direction — say the highest high since the last confirmed low. As long as price keeps making new extremes, the endpoint of the current line moves with it. Only when price reverses from that extreme by the full threshold (for example 5%) does the algorithm lock in the extreme as a confirmed pivot and begin drawing a new leg in the opposite direction. This mechanic is exactly why ZigZag repaints: until the reversal threshold is met, the 'pivot' you see on the last leg is a running maximum or minimum that can be relocated many bars later, or erased entirely if price resumes the prior move. Pivot-depth variants (built on functions like ta.pivothigh) have the same property in a different form — a swing high with a right-side depth of 10 bars cannot be known until 10 bars after it printed. Confirmation delay is not a flaw to be optimized away; it is the mathematical price of identifying a swing at all.
Percentage-based versions commonly default to a 5% reversal (often lowered to 1–3% on intraday charts and raised on volatile instruments). Point/tick-based versions use an absolute price distance. Pivot-based versions use a depth such as 10 bars on each side. There is no correct setting — smaller thresholds show more, smaller swings; larger thresholds show fewer, larger ones — and every reading changes with the threshold, so settings should always be disclosed alongside any analysis.
//@version=6
indicator("ZigZag Pivots (Non-Repainting Marks)", overlay = true)
leftBars = input.int(10, "Left Bars", minval = 1)
rightBars = input.int(10, "Right Bars", minval = 1)
// A swing is only KNOWN rightBars after it forms — that delay is the
// honest cost of confirmation. ta.pivothigh/ta.pivotlow return a value
// only on the confirmation bar, never earlier.
ph = ta.pivothigh(high, leftBars, rightBars)
pl = ta.pivotlow(low, leftBars, rightBars)
// Marks are drawn on the confirmation bar, NOT shifted back to the pivot
// itself, so nothing on this chart repaints or peeks into the future.
confHigh = not na(ph) and barstate.isconfirmed
confLow = not na(pl) and barstate.isconfirmed
plotshape(confHigh, "Swing High Confirmed", style = shape.triangledown, location = location.abovebar, color = color.red, size = size.tiny)
plotshape(confLow, "Swing Low Confirmed", style = shape.triangleup, location = location.belowbar, color = color.green, size = size.tiny)
alertcondition(confHigh or confLow, "Pivot Confirmed", "A swing pivot was confirmed (with built-in delay).")Pro tip: If you want to study swing structure honestly, mark pivots on the bar where they are confirmed rather than shifting them back to where they occurred — the difference between those two charts is exactly the information a live trader never had. Run any ZigZag-based logic through a repaint check before trusting it, and treat the tool as a lens for completed structure, not a trigger. Educational context only, not financial advice; all trading involves risk of loss.
Educational only — not financial advice, not a recommendation to trade. No indicator is predictive; trading involves substantial risk of loss.