Files
wickra/docs/wiki/indicators/volatility/Indicator-SuperTrend.md
T
kingchenc 21bbd521b3 F11: add SuperTrend, Chandelier Exit, Chande Kroll Stop and ATR Trailing Stop
- Rust core: super_trend.rs (SuperTrend — ATR-banded trailing stop with
  flip logic; SuperTrendOutput { value, direction }), chandelier_exit.rs
  (Chandelier Exit — ATR stop hung off the window's highest high / lowest
  low; ChandelierExitOutput { long_stop, short_stop }),
  chande_kroll_stop.rs (Chande Kroll Stop — a two-stage ATR stop;
  ChandeKrollStopOutput { stop_long, stop_short }), atr_trailing_stop.rs
  (ATR Trailing Stop — a single ratcheting close-based stop). Each with a
  full Indicator impl, runnable doctest and reference / property / warmup
  / reset / batch==streaming tests.
- Python: PySuperTrend / PyChandelierExit / PyChandeKrollStop /
  PyAtrTrailingStop PyO3 classes (struct outputs as tuples and (n, 2)
  arrays) + module registration + .pyi stubs.
- Node: explicit SuperTrendNode / ChandelierExitNode / ChandeKrollStopNode
  / AtrTrailingStopNode with SuperTrendValue / ChandelierExitValue /
  ChandeKrollStopValue objects; index.d.ts and index.js updated.
- WASM: WasmSuperTrend / WasmChandelierExit / WasmChandeKrollStop /
  WasmAtrTrailingStop.
- Wiki: Indicator-SuperTrend/ChandelierExit/ChandeKrollStop/
  AtrTrailingStop.md plus rows in the "Trailing stop" table of
  Indicators-Overview.md and entries in Home.md.
- Add clippy.toml with doc-valid-idents for the proper noun "LeBeau".

cargo fmt + clippy (core/wickra/data/wasm/node) clean; 427 core tests,
25 data tests and 61 doctests green.
2026-05-22 19:42:14 +02:00

5.4 KiB
Raw Blame History

SuperTrend

SuperTrend — an ATR-banded trailing stop that flips sides when price closes through the band, reporting both the stop level and the trend direction.

Quick reference

Field Value
Family Volatility
Sub-category Trailing stop
Input type Candle (uses high, low, close)
Output type (value, direction)
Output range value: unbounded (price scale); direction: 1.0 or +1.0
Default parameters atr_period = 10, multiplier = 3.0 (Python)
Warmup period atr_period
Interpretation Trend-following stop; a direction flip marks a trend change.

Formula

hl2          = (high + low) / 2
basic_upper  = hl2 + multiplier · ATR
basic_lower  = hl2  multiplier · ATR

final_upper  = basic_upper  if basic_upper < prev_final_upper or prev_close > prev_final_upper
               else prev_final_upper
final_lower  = basic_lower  if basic_lower > prev_final_lower or prev_close < prev_final_lower
               else prev_final_lower

downtrend: stay down while close <= final_upper, else flip up
uptrend:   stay up   while close >= final_lower, else flip down
SuperTrend = final_lower in an uptrend, final_upper in a downtrend

The two final bands ratchet — the upper band only moves down, the lower band only moves up — until price closes through the active one. That close flips the trend and hands the trailing-stop role to the opposite band. The result is a single line that sits below price in an uptrend and above it in a downtrend, plus a direction flag (+1.0 / -1.0) that names which regime you are in.

Parameters

  • atr_period — the ATR lookback (Python default 10).
  • multiplier — how many ATRs wide the bands sit (Python default 3.0).

SuperTrend::classic() returns Wilder's (10, 3.0) configuration.

Inputs / Outputs

From crates/wickra-core/src/indicators/super_trend.rs:

impl Indicator for SuperTrend {
    type Input = Candle;
    type Output = SuperTrendOutput;   // { value: f64, direction: f64 }
    // update(&mut self, input: Candle) -> Option<SuperTrendOutput>
}

SuperTrend is a candle-input indicator (it reads high, low, close). Python's streaming update returns a (value, direction) tuple; the batch helper returns an (n, 2) array with columns [value, direction]. Node's update returns { value, direction } and batch a flat [v0, d0, v1, d1, …] array; WASM matches Node.

Warmup

SuperTrend::classic().warmup_period() == 10. The first value lands once the inner ATR is ready, on input index atr_period 1. The first ATR-ready bar seeds the trend as up; the flip logic corrects it within a few bars if the market is actually falling.

Edge cases

  • Seed direction. The first emitted bar is always direction = +1.0; a genuine downtrend flips it within a handful of bars.
  • Flat market. Constant candles give a constant ATR, so both bands and the line are flat and the trend never flips.
  • Reset. st.reset() clears the ATR and the carried band state.

Examples

Rust

use wickra::{BatchExt, Candle, Indicator, SuperTrend};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut st = SuperTrend::new(5, 3.0)?;
    // Flat market: ATR = 2, hl2 = 10, lower band = 10 - 3·2 = 4.
    let candles: Vec<Candle> = (0..20)
        .map(|i| Candle::new(10.0, 11.0, 9.0, 10.0, 1.0, i).unwrap())
        .collect();
    let out = st.batch(&candles);
    println!("{:?}", out.last().unwrap());
    Ok(())
}

Output:

Some(SuperTrendOutput { value: 4.0, direction: 1.0 })

On a flat market the seeded uptrend never flips and the line holds at the lower band, 4.0.

Python

import numpy as np
import wickra as ta

st = ta.SuperTrend(5, 3.0)
n = 20
high = np.full(n, 11.0)
low = np.full(n, 9.0)
close = np.full(n, 10.0)
print(st.batch(high, low, close)[-1])   # [value, direction]

Output:

[4. 1.]

Node

const ta = require('wickra');
const st = new ta.SuperTrend(5, 3.0);
const n = 20;
const high = Array(n).fill(11), low = Array(n).fill(9), close = Array(n).fill(10);
const out = st.batch(high, low, close);
console.log(out.slice(-2));   // [value, direction] of the last bar

Output:

[ 4, 1 ]

Interpretation

SuperTrend is used as a stop-and-reverse system: stay long while direction == +1 and the line trails below price, flip to short the bar the direction turns -1 and the line jumps above price. A larger multiplier widens the bands — fewer whipsaws, later flips; a smaller one flips sooner. The line itself doubles as a concrete stop-loss level.

Common pitfalls

  • Expecting an exact flip bar. The seed bar is always an uptrend; on genuinely falling data the flip lands a few bars in.
  • Reading value without direction. The line means "support" in an uptrend and "resistance" in a downtrend — direction tells you which.

References

The SuperTrend trailing stop; the final-band ratchet formulation here matches the widely used TradingView / Olivier Seban definition.

See also