TradingView indicators

Volatility Stop on TradingView: State, ATR and Reversals

The Volatility Stop indicator is a stateful ATR trailing line. Within an upward state it can only rise; within a downward state it can only fall. A reversal tests price against the candidate stop, then resets the line on the opposite side of price. That order matters when reproducing its values.

This guide defines an auditable close-based version, including its warm-up and equality rules. The table and Pine code use the same algorithm. They are an educational reference, not a claim to reproduce every public or protected VStop script.

Worked reversal: a previous stop of 103.111111 stays fixed while ATR expands. A gap bar closes at 98, flips the state downward and resets the final plotted stop to 103.283951. The final plotted line is not the level that triggered the flip.

Specify the state before comparing lines

TradingView's open-source Volatility Stop describes an ATR trend detector that can also serve as a stop guide. The implementation below uses closes for its running extremes and confirms updates at the chart bar's close. Its explicit initialization is part of the definition.

  1. Compute volatility. True range is max(high − low, |high − previous close|, |low − previous close|). On the first available bar, use high − low. ATR is Wilder's RMA of true range: seed with the mean of the first N valid true ranges, then ATR = ((N − 1) × previous ATR + current TR) / N. Distance D = multiplier × ATR.
  2. Initialize once ATR exists. Until then, show no stop. On the first confirmed bar with ATR, set peak = trough = close, state = up, and stop = close − D. Initialization emits no reversal alert. The starting direction is a convention, not evidence that a trend has begun.
  3. Update extremes and the candidate. Extend peak and trough with the current close. If the previous state is up, candidate = max(previous stop, peak − D). If it is down, candidate = min(previous stop, trough + D).
  4. Decide the new state. Set next state to up when close ≥ candidate, otherwise down. Compare with the candidate before resetting anything.
  5. Reset only on a reversal. If the state changed, set both extremes to the current close and the final stop to close − D for up or close + D for down. Otherwise retain the candidate. Save the new state for the next bar.

ATR uses the chart's OHLC data even though the extreme source is close. Changing the source to HL2 does not change the ATR formula or automatically provide close confirmation. See TradingView's ATR documentation and the ta.atr reference.

Eight OHLC bars, including a wick and two gaps

These are synthetic prices in arbitrary price units, not market observations or performance results. Set N = 3, multiplier = 1 and source = close. Bar 1 is the first available bar. Calculations retain full precision; the table rounds to six decimals.

Confirmed-close VStop state trace (ATR length 3, multiplier 1)
BarOpen / High / Low / CloseTRATRCandidateFinal stopFinal state
1100 / 102 / 100 / 1012Not seededNoneNoneWarm-up
2101 / 103 / 101 / 1022Not seededNoneNoneWarm-up
3102 / 104 / 101 / 10332.333333Initialize100.666667Up (seed)
4103 / 107 / 103 / 10642.888889103.111111103.111111Up
5106 / 107 / 101 / 10563.925926103.111111103.111111Up (wick)
699 / 100 / 97 / 9885.283951103.111111103.283951Down (gap)
798 / 99 / 95 / 9644.855967100.855967100.855967Down
8103 / 105 / 102 / 10496.237311100.85596797.762689Up (gap)

Bar 4 ratchet: the highest close is 106. ATR = (2 × 2.333333… + 4) / 3 = 2.888888…. The candidate rises to max(100.666667, 106 − 2.888889) = 103.111111.

Bar 5 intrabar crossing: its low of 101 is below the stop, but its close is 105. The candidate stays at 103.111111 because the new ATR distance would otherwise lower it. This close-confirmed version keeps the upward state. OHLC alone cannot reconstruct every intermediate tick or the order of the high and low.

Bar 6 gap: the previous close is 105, so TR = max(3, 5, 8) = 8, not just high − low = 3. The close of 98 is below the candidate 103.111111. After the flip, both extremes reset to 98 and the new down stop becomes 98 + 5.283951 = 103.283951.

Bar 8 reverse gap: TR = max(3, 9, 6) = 9. The down candidate remains 100.855967, then close 104 selects up. The reset yields 104 − 6.237311 = 97.762689. Comparing close with this final line would obscure which boundary caused the reversal.

Pine Script v6 with explicit close confirmation

Paste this indicator into TradingView's Pine Editor and add it to a standard candlestick chart. The inputs default to 20 and 2; change them to 3 and 1 when checking the synthetic arithmetic separately. The code plots a guide and defines alert conditions. It places no orders.

Pine Script v6

//@version=6
indicator("Volatility Stop: confirmed-close reference", overlay = true)
int length = input.int(20, "ATR length", minval = 1)
float factor = input.float(2.0, "ATR multiplier", minval = 0.01, step = 0.1)
float atr = ta.atr(length)
var float peak = na
var float trough = na
var float stop = na
var bool up = true
bool flippedUp = false
bool flippedDown = false

// Wait for a seeded ATR. Commit state only when the chart bar closes.
if barstate.isconfirmed and not na(atr)
    float distance = factor * atr
    if na(stop)
        peak := close
        trough := close
        up := true
        stop := close - distance
    else
        peak := math.max(peak, close)
        trough := math.min(trough, close)
        float candidate = up ? math.max(stop, peak - distance) : math.min(stop, trough + distance)
        bool nextUp = close >= candidate
        flippedUp := nextUp and not up
        flippedDown := not nextUp and up
        if nextUp != up
            peak := close
            trough := close
            stop := nextUp ? close - distance : close + distance
        else
            stop := candidate
        up := nextUp

plot(stop, "Confirmed VStop", color = up ? color.teal : color.red, style = plot.style_stepline)
plot(up ? 1 : -1, "State: up 1, down -1", display = display.data_window)
plot(atr, "ATR", display = display.data_window)
plotshape(flippedUp, title = "Up reversal", style = shape.triangleup, location = location.belowbar, color = color.teal, text = "UP", size = size.tiny)
plotshape(flippedDown, title = "Down reversal", style = shape.triangledown, location = location.abovebar, color = color.red, text = "DOWN", size = size.tiny)
alertcondition(flippedUp, "VStop up reversal", "Confirmed VStop up reversal")
alertcondition(flippedDown, "VStop down reversal", "Confirmed VStop down reversal")

The ATR calculation executes on every update, while the persistent state changes only inside barstate.isconfirmed. On an open bar the line retains its previous confirmed value. Pine indicators otherwise recalculate as prices update, with rollback between ticks; using close as a source alone does not make a script close-confirmed. See the Pine execution model and bar-state documentation.

For an alert, select either reversal condition and use Once Per Bar Close. The seed bar does not count as a flip. Recreate an existing alert after changing the script or its inputs because TradingView alerts retain a snapshot of their original configuration. TradingView alert behavior.

VStop versus a rolling Chandelier Exit

A standard Chandelier Exit anchors its long line to the highest high in a fixed lookback and its short line to the lowest low in that lookback. This VStop anchors to closes since its last state reset and applies a one-way ratchet. The ATR length does not define the age of its peak or trough.

Suppose a rolling highest high falls from 110 to 108 when an old bar leaves the window, with ATR distance fixed at 4. The unratcheted Chandelier long level falls from 106 to 104. An upward VStop already at 106 remains at least 106 until reversal. Custom Chandelier scripts can add a ratchet, so compare formulas rather than names.

Conditions that break a naive comparison

  • Different history lengths or warm-up fallbacks can produce different starting states. This example deliberately waits for ATR; another script may substitute true range immediately.
  • A gap may jump over an executable stop. An indicator line is not a guaranteed fill price, and waiting for close may recognize an exit much later than a resting order.
  • Small alternating closes near the candidate can cause repeated reversals. Larger multipliers change that tradeoff but do not establish profitability.
  • Adjusted prices, sessions and synthetic chart types can change OHLC, ATR and the resulting state. Compare the same symbol, session, timeframe and standard chart data.
  • Zero ATR places the initial stop at the close despite a positive multiplier. Equality follows the stated upward convention; a positive distance is not guaranteed in a flat series.

Educational material only, not investment advice. Syntax validation does not prove signal quality, fills or future returns.

Turn the documented rules into a script you can compare

Pineify's Pine Script AI Coding Agent can create and edit Pine code from a written specification and offers syntax checking. Provide the initialization, ATR smoothing, source, equality rule and close condition together. Review the resulting source before relying on its plots or alerts.

Example request: "Keep the confirmed-close VStop rules on this page. Expose ATR length and multiplier. Add Data Window values for the candidate and the running extremes so I can compare each closed bar. Preserve the no-alert initialization rule."

Compare closed-bar values in TradingView's Data Window before creating alerts. A public formula can be implemented and tested; a protected script's private source cannot be inferred reliably from its name or screenshot.

Open Pine Script AI Coding Agent

Volatility Stop questions

A wick alone does not reverse this confirmed-close implementation. The final close is compared with the candidate stop. A live version can change direction during a bar because close is the latest price until that bar closes. A broker stop order may execute on the wick even when the indicator keeps its direction.

Matching ATR length and multiplier is not enough. Compare the source, ATR smoothing, initialization, historical starting bar, equality rule, update order and intrabar confirmation. This example waits for ATR to become available and initializes upward. It does not promise identical values to every script named Volatility Stop.

An established upward state cannot lower its stop in this implementation: the candidate is the maximum of the previous stop and the running highest close minus the ATR distance. Rising ATR can prevent further tightening. A reversal resets the line on the other side of price.

Equality selects the upward state because the comparison is close >= candidate. An upward state remains upward; a downward state reverses upward. Changing this comparison changes boundary behavior, so preserve it when comparing implementations.

Length 20 and multiplier 2 are starting inputs in the example, not a tested optimum. Evaluate settings on your own symbol, session and timeframe with costs and unseen data. Sideways price can cause repeated reversals, and a wider distance can increase the loss before an exit.

Continue with the TradingView indicator library, ATR or Supertrend. Official references checked October 17, 2026.