TradingView indicators

Vortex Indicator: formula, crossovers and limits

The Vortex Indicator compares two rolling price-movement ratios, VI+ and VI-. VI+ uses the current high and previous low; VI- uses the current low and previous high. Both are divided by the same sum of true range. Their crossovers describe a change in directional balance, but can reverse repeatedly in a sideways market.

Use the calculation table to check the bar indexes, then copy the adjustable Pine Script example. Its crossover markers wait for the chart candle to close.

Hypothetical result · Length 2 · Bar 3

VI+ = 3 / 6 = 0.500 · VI- = 6 / 6 = 1.000

VI- moves above VI+ after a downward bar. The table below supplies every input; this is an arithmetic demonstration, not a backtest.

Calculate Vortex from adjacent bars

For bar t, use high and low from t, but the previous extremes and close from t-1. Never substitute the current low for the previous low in VM+, or the current high for the previous high in VM-. Those substitutions would turn both numerators into the same high-low range.

VM+(t) = |High(t) - Low(t-1)|

VM-(t) = |Low(t) - High(t-1)|

TR(t) = max(High(t) - Low(t), |High(t) - Close(t-1)|, |Low(t) - Close(t-1)|)

VI+(t) = sum(VM+, n) / sum(TR, n)

VI-(t) = sum(VM-, n) / sum(TR, n)

Each sum includes the current bar and the preceding n-1 movement values. The table uses invented prices in arbitrary price units. Bar 0 only supplies the previous prices; three movements require four price bars.

Demonstration data, not market observations
BarHighLowCloseVM+VM-TR
01089Seed barSeed barSeed bar
111910|11 - 8| = 3|9 - 10| = 1max(2, 2, 0) = 2
2121011|12 - 9| = 3|10 - 11| = 1max(2, 2, 0) = 2
31078|10 - 10| = 0|7 - 12| = 5max(3, 1, 4) = 4

With n=2 at bar 2, the sums are VM+=6, VM-=2 and TR=4, giving 1.500 and 0.500. At bar 3, bar 1 leaves the window: VM+=3, VM-=6 and TR=6, giving 0.500 and 1.000. VI- has crossed above VI+. Notice that bar 3 has a high-low range of 3 but TR of 4 because its low is 4 below the previous close.

The positive denominator changes each line's magnitude, but it cannot change which line is larger. A line may exceed 1 because its numerator and TR measure different distances. Neither 1 nor a particular line separation is a universal entry threshold.

Pine Script v6 with explicit boundary handling

Paste the complete code into a new TradingView indicator, save it and add it to your chart. Length defaults to 14 and has a minimum of 1. Inspect the two plotted values in the Data Window. Blue upward triangles and magenta downward triangles mark closed-bar crossovers; they are observations, not executed orders.

Pine Script v6 · Indicator
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Pineify
//@version=6
indicator("Vortex Indicator: confirmed crossovers", overlay=false)

length = input.int(14, "Length", minval=1)

p_ta_vi(simple int length) =>
    valid = not na(high) and not na(low) and not na(high[1]) and not na(low[1]) and not na(close[1])
    vmPlus = valid ? math.abs(high - low[1]) : 0.0
    vmMinus = valid ? math.abs(low - high[1]) : 0.0
    trueRange = valid ? math.max(high - low, math.max(math.abs(high - close[1]), math.abs(low - close[1]))) : 0.0
    sumPlus = math.sum(vmPlus, length)
    sumMinus = math.sum(vmMinus, length)
    sumTR = math.sum(trueRange, length)
    ready = math.sum(valid ? 1.0 : 0.0, length) == length and sumTR > 0
    [ready ? sumPlus / sumTR : na, ready ? sumMinus / sumTR : na]

[viPlus, viMinus] = p_ta_vi(length)
crossUp = ta.crossover(viPlus, viMinus)
crossDown = ta.crossunder(viPlus, viMinus)
confirmedUp = barstate.isconfirmed and crossUp
confirmedDown = barstate.isconfirmed and crossDown

plot(viPlus, "VI+", color=color.blue, linewidth=2)
plot(viMinus, "VI-", color=color.fuchsia, linewidth=2)
hline(1.0, "Reference 1.0", color=color.gray)
plotshape(confirmedUp, "Confirmed VI+ crossover", shape.triangleup, location.bottom, color.blue, size=size.tiny)
plotshape(confirmedDown, "Confirmed VI- crossover", shape.triangledown, location.top, color.fuchsia, size=size.tiny)
alertcondition(confirmedUp, "VI+ crossover", "VI+ crossed above VI- on a closed chart bar.")
alertcondition(confirmedDown, "VI- crossover", "VI- crossed above VI+ on a closed chart bar.")
  • The validity count requires n consecutive usable movements. Missing required high, low or previous-close data invalidates the window rather than silently shortening it.
  • With complete prices, length 14 first produces a value on loaded bar index 14, the fifteenth bar. A crossover also needs a valid prior reading.
  • A window with sum(TR)=0 returns na for both lines. Replacing that denominator with a tiny constant would manufacture a reading.
  • The lines still update on an open candle. Only the markers and alert conditions wait for barstate.isconfirmed. Configure an alert with Once Per Bar Close.

Length sensitivity and settings

Changing length changes which movements enter the ratio. On the same demonstration bar 3, the values differ even though the current price is identical. These short lengths make the arithmetic visible; they are not recommended trading settings.

LengthMovement barsVI+VI-Can bar 3 mark a cross?
130 / 4 = 0.0005 / 4 = 1.250Yes, after close
22, 33 / 6 = 0.5006 / 6 = 1.000Yes, after close
31, 2, 36 / 8 = 0.7507 / 8 = 0.875No prior valid reading

A shorter window replaces a larger fraction of its observations each bar. A longer window retains older movement for more bars, so it can react later to a reversal. Neither choice removes whipsaws. Length counts chart bars, not calendar days: 14 hourly bars and 14 daily bars describe different histories.

For a settings study, fix the symbol, timeframe, session and trading rules first. Compare a small declared set such as 7, 14 and 21, then reserve another period for validation. Record turnover, drawdown and costs alongside returns. This page has not tested that set or established an optimal length for any asset.

From a confirmed crossover to a testable rule

Confirmation here means the chart candle has closed. It does not confirm a profitable trend. In a range, new highs and lows can alternate the two movement sums and trigger a series of opposing crossovers.

  1. Reproduce several closed-bar readings against TradingView's Vortex indicator with the same length and chart data. Check startup bars and gaps separately if values differ.
  2. Specify a complete hypothesis. For example, evaluate a long entry after a confirmed VI+ crossover and an exit after the opposite confirmed crossover. Define whether short positions are permitted, how position size is chosen and what loss limit applies.
  3. State execution timing before measuring results. A close-confirmed signal and its simulated fill are separate events. TradingView strategies normally fill a new market order at the next available tick, commonly the next bar's open with default bar-close calculation.
  4. Include commission and slippage, then test another time period. A minimum line gap or price-trend filter changes the strategy; compare its trade count and missed moves as well as any reduction in reversals.

Educational calculation and code only, not investment advice. The indicator has no position sizing, orders, exits or performance results. A successful syntax check does not validate a trading strategy or guarantee future returns.

Continue the implementation in Pineify

Give the Pine Script AI Coding Agent the example, length, desired confirmation timing and boundary rules. Ask it to preserve the two ratios and expose their values before adding strategy orders. Review the generated source, compare closed-bar outputs, and define exits and costs separately.

Open Pine Script AI Coding Agent

Vortex Indicator questions

VI+ above VI- means the rolling positive vortex movement sum exceeds the negative sum. A crossover changes that ordering. Both lines share the same positive true-range denominator. The reading describes recent prices; it does not measure buying volume or establish that the next bar will continue in the same direction.

This guide establishes no universally best setting. The script starts at 14 bars and accepts a positive integer length. Compare a few lengths using the same symbol, timeframe, session, entry and exit rules, and costs. Judge the choice on a separate validation period instead of selecting only the highest historical profit.

The numerator connects a current extreme to the opposite extreme of the previous bar. True range measures a different set of distances. The numerator can exceed the denominator, so 1 is a reference level rather than a ceiling. In the demonstration, two consecutive rising bars produce VI+ of 1.5 with length 2.

The two lines can move while the current candle is open because high and low can change. The example waits for barstate.isconfirmed before displaying a crossover marker or satisfying an alert condition. This addresses open chart-bar signals; it does not prevent data revisions or establish the behavior of a separate higher-timeframe implementation.

Each vortex movement needs the preceding bar, and the script requires a full window of valid movements. With length 14 and complete prices, the first output is on the fifteenth loaded bar. A zero true-range sum or a window containing missing required prices also returns na. The first valid reading alone is not a crossover.

Create an indicator in Pine Editor, replace its contents with the complete example, save it, and add it to the chart. Set Length in the indicator settings. Use the Data Window to inspect VI+ and VI- on closed bars. For notifications, create a TradingView alert using one of the script conditions and select Once Per Bar Close.

Vortex compares two directional movement totals built from adjacent high and low prices. Its line ordering is a directional reading. ADX is used to assess trend strength without specifying its direction. This page does not assign an ADX threshold to Vortex values: the calculations and scales are different.

Sources and related reading

Official documentation checked October 17, 2026. The worked numbers and implementation guards are this guide's demonstration.

Browse TradingView indicator guides or compare the distinct strength measurement in the ADX guide.