Swing Structure & Break of Structure Marker
A market structure indicator that identifies swing highs and lows, then labels points where price breaks previous structure (BOS: Break of Structure) or reverses the market's character (CHoCH: Change of Character). Used by traders following price action and supply/demand methodologies to spot potential reversal zones and confirm directional shifts.
//@version=6
indicator("Swing Structure & BOS/CHoCH", overlay=true, max_labels_count=500)
// Inputs
lookback = input.int(2, "Swing Lookback Bars", minval=1, maxval=20)
showLabels = input.bool(true, "Show Labels")
showSwingMarkers = input.bool(true, "Show Swing Points")
bosColor = input.color(color.new(color.blue, 60), "BOS Color")
chochColor = input.color(color.new(color.red, 60), "CHoCH Color")
// Identify swing highs and lows
isSwingHigh = high[lookback] > ta.highest(high, lookback * 2 + 1) and high[lookback] == ta.highest(high, lookback)
isSwingLow = low[lookback] < ta.lowest(low, lookback * 2 + 1) and low[lookback] == ta.lowest(low, lookback)
var float lastSwingHigh = na
var float lastSwingLow = na
var int lastSwingHighBar = na
var int lastSwingLowBar = na
var bool lastStructure = na // true = uptrend, false = downtrend
// Track swing points
if isSwingHigh
lastSwingHigh := high[lookback]
lastSwingHighBar := bar_index - lookback
if isSwingLow
lastSwingLow := low[lookback]
lastSwingLowBar := bar_index - lookback
// Detect BOS and CHoCH
isBosAbove = not na(lastSwingHigh) and close > lastSwingHigh and lastStructure != true
isBosBelow = not na(lastSwingLow) and close < lastSwingLow and lastStructure != false
isChochAbove = isBosAbove and lastStructure == false
isChochBelow = isBosBelow and lastStructure == true
// Update structure
if isBosAbove
lastStructure := true
if isBosBelow
lastStructure := false
// Plot swing markers
if showSwingMarkers
if isSwingHigh
plot(high[lookback], "Swing High", color.new(color.orange, 50), 2, plot.style_circles)
if isSwingLow
plot(low[lookback], "Swing Low", color.new(color.teal, 50), 2, plot.style_circles)
// Add labels
if showLabels
if isChochAbove
label.new(bar_index, high + (ta.atr(14) * 0.5), "CHoCH",
color=chochColor, style=label.style_label_down, textcolor=color.white)
if isChochBelow
label.new(bar_index, low - (ta.atr(14) * 0.5), "CHoCH",
color=chochColor, style=label.style_label_up, textcolor=color.white)
if isBosAbove and lastStructure == true
label.new(bar_index, high + (ta.atr(14) * 0.3), "BOS",
color=bosColor, style=label.style_label_down, textcolor=color.white)
if isBosBelow and lastStructure == false
label.new(bar_index, low - (ta.atr(14) * 0.3), "BOS",
color=bosColor, style=label.style_label_up, textcolor=color.white)
How the code works
The indicator first identifies swing points using a lookback period. A swing high forms when a bar's high is greater than all bars within a window spanning lookback bars on either side; a swing low is identified symmetrically for lows. This prevents false swings from minor noise.
The script maintains variables for the most recent swing high and swing low, recording both their price level and the bar index at which they formed. It tracks a "structure state" (uptrend or downtrend) that flips when price violates previous swings.
A Break of Structure (BOS) occurs when price closes above the last swing high after the structure was bearish, or closes below the last swing low after the structure was bullish. This signals potential reversal or continuation depending on context. A Change of Character (CHoCH) is a special BOS: the first break of the previous structure in the opposite direction, marking the inflection point.
The indicator plots swing points as small circles and labels BOS and CHoCH events on the chart. Label placement accounts for average true range (ATR) to avoid crowding the price bars.
Reading it on a chart
Swing high and low markers (teal and orange circles) show the local peaks and valleys the indicator tracks. These are potential supply (highs) and demand (lows) zones.
When the "BOS" label appears, price has broken a previous swing level; this may signal the start of a directional move or a failed reversal, depending on the broader context. The "CHoCH" label marks a more significant event: the first structural break in a new direction, often watched by traders as a confluent reversal zone.
Confluence happens when a BOS aligns with support/resistance, moving averages, or volume nodes. Standalone labels without other confirming signals carry less weight.
Limitations
The indicator lags: swings are identified only after enough bars have passed to confirm they are true local extremes. Depending on lookback settings, this can be 4-8 bars after the actual pivot, leaving little room to act on the signal.
The simple high/low logic is vulnerable to wicks and outliers. A single spike can create a swing high or low that breaks immediately on the next bar, generating false BOS labels in choppy or gapping markets.
The script does not distinguish between impulsive moves (likely to continue) and corrective pullbacks (likely to reverse). A CHoCH is not a buy or sell signal on its own; it is only a structural reversal marker. Many false reversals occur without confirmation from volume, momentum, or order flow.
Lookback period tuning is non-trivial: too short and noise dominates, too long and meaningful structure is missed. Optimal values vary by timeframe and asset, requiring manual optimization.
The script assumes clean, non-gapping data. Gap opens can violate swing levels instantly, producing labels before the market actually traded at those prices, which distorts supply/demand interpretation.
Key definitions
Swing High: A local price peak where the high bar is elevated relative to the bars immediately to its left and right, representing a potential resistance or supply level.
Swing Low: A local price trough where the low bar is depressed relative to the bars immediately to its left and right, representing a potential support or demand level.
Break of Structure (BOS): A close beyond a previous swing high or swing low, signaling a shift in short-term directional momentum or the failure of a support/resistance level.
Change of Character (CHoCH): The first BOS in a direction opposite to the prior trend, marking the inflection point where structure reverses from uptrend to downtrend or vice versa.
Lookback Period: The number of bars to the left and right of a candidate pivot used to confirm it is a true swing, with higher values filtering out minor noise.
Supply & Demand: Levels where concentrated buying (demand) or selling (supply) has created support or resistance; highs often represent supply zones and lows represent demand zones.
References
- Investopedia, "Support and Resistance in Technical Analysis", Investopedia (2023). Https://www.investopedia.com/terms/s/support.asp
- TradingView, "Pine Script Documentation: Technical Analysis Functions", TradingView (2024). Https://www.tradingview.com/pine-script-docs/
- CME Group, "Futures Primer: Understanding Price Action", CME Education (2022). Https://www.cmegroup.com/education/
Educational research on historical data only. Not investment advice, not a signal, and never a performance promise. Past results do not predict future performance. Every reference is link-verified before publication and every paper is re-audited weekly against the library's editorial standard.
Last reviewed by the PropLedger research pipeline: 2026-08-30. Educational research on historical data, not financial advice.