Vortex
Vortex Indicator — a pair of oscillators (
VI+,VI−) whose crossings identify the start of a new trend.
Quick reference
| Field | Value |
|---|---|
| Family | Trend & Directional |
| Input type | Candle (uses high, low, close) |
| Output type | VortexOutput { plus, minus } |
| Output range | each line >= 0, typically around 1.0 |
| Default parameters | period = 14 (Python) |
| Warmup period | period + 1 |
| Interpretation | VI+ above VI− = up-trend; the cross marks the turn. |
Formula
VM+_t = |high_t − low_{t−1}| (positive vortex movement)
VM−_t = |low_t − high_{t−1}| (negative vortex movement)
TR_t = true range
VI+ = Σ VM+ over period / Σ TR over period
VI− = Σ VM− over period / Σ TR over periodEach vortex movement measures how far this bar reached against the opposite extreme of the previous bar; dividing the running sums by the running true range normalises both lines to a comparable scale around 1.0. VI+ crossing above VI− signals a new up-trend; the reverse, a down-trend.
Parameters
| Name | Type | Default | Valid range | Description |
|---|---|---|---|---|
period | usize | 14 (Python) | >= 1 | Summation window. 0 errors with Error::PeriodZero. |
The Python binding defaults period to 14.
Inputs / Outputs
From crates/wickra-core/src/indicators/vortex.rs:
use wickra::{Indicator, Vortex, Candle, VortexOutput};
// Vortex: Input = Candle, Output = VortexOutput
const _: fn(&mut Vortex, Candle) -> Option<VortexOutput> = <Vortex as Indicator>::update;Vortex is a candle-input indicator reading high, low and close. The streaming update returns VortexOutput (Rust), (plus, minus) (Python), or { plus, minus } (Node/WASM). The batch helper returns one row per input — a (n, 2) numpy array in Python, a flat [plus, minus, …] array of length 2·n in Node/WASM, with NaN during warmup.
Warmup
Vortex::new(period).warmup_period() == period + 1. The first VM/TR triple needs a previous bar, so it forms on bar 2; the summation window then needs period triples — the first output lands on input period + 1.
Edge cases
- Flat market. A window with zero total true range cannot be normalised; both lines are reported as
0.0(perfectly_flat_market_yields_zeropins this). - Non-negative. Both
VI+andVI−are sums of absolute values over a non-negative range, so neither is ever negative (outputs_are_non_negativepins this). - Candle validation.
Candle::newrejects invalid bars upstream. - Reset.
vortex.reset()clears the previous bar, the window and the three running sums.
Examples
Rust
use wickra::{BatchExt, Candle, Indicator, Vortex};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let candles = [
Candle::new(9.0, 10.0, 8.0, 9.0, 1.0, 0)?,
Candle::new(10.0, 12.0, 9.0, 11.0, 1.0, 1)?,
Candle::new(12.0, 13.0, 11.0, 12.0, 1.0, 2)?,
];
let mut v = Vortex::new(2)?;
let out = v.batch(&candles);
println!("{:?}", out[2]);
Ok(())
}Output:
Some(VortexOutput { plus: 1.6, minus: 0.4 })Over the two formed bars Σ VM+ = 8, Σ VM− = 2, Σ TR = 5, giving VI+ = 1.6 and VI− = 0.4. This matches the reference_values test in crates/wickra-core/src/indicators/vortex.rs.
Python
import numpy as np
import wickra as ta
v = ta.Vortex(14)
high = np.array([10.0, 12.0, 13.0])
low = np.array([8.0, 9.0, 11.0])
close = np.array([9.0, 11.0, 12.0])
# v.batch(high, low, close) -> (3, 2) array of [plus, minus], NaN during warmup
print(v.update((9.0, 10.0, 8.0, 9.0, 1.0, 0)))Node
const ta = require('wickra');
const v = new ta.Vortex(14);
console.log(v.update(12, 9, 11)); // { plus, minus } or null during warmupInterpretation
Vortex is a trend-onset detector. The signal is the crossing: when VI+ rises above VI−, a new up-trend is starting; when VI− rises above VI+, a down-trend. The gap between the lines measures conviction — a wide, widening gap is a strong trend, converging lines warn of a stall. Unlike a lagging moving-average cross, the vortex movements react to the reach of each bar, so the cross tends to fire early.
Common pitfalls
- Reading the lines in isolation. A
VI+of1.1means nothing on its own — what matters is its position relative toVI−. - Feeding it scalar prices. It needs
high/low/close.
References
Etienne Botes and Douglas Siepman, "The Vortex Indicator", Technical Analysis of Stocks & Commodities (2010). The VM± / true-range definition here follows their original.
See also
- Indicator-Adx — Wilder's directional system.
- Indicator-Atr — the true range Vortex normalises against.
- Indicators-Overview — the full taxonomy.