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

175 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`:
```rust
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
```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
```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
```javascript
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
- [Indicator-Psar.md](Indicator-Psar.md) — Wilder's parabolic stop-and-reverse.
- [Indicator-AtrTrailingStop.md](Indicator-AtrTrailingStop.md) — a plain
ATR trailing stop without the band ratchet.
- [Indicator-Atr.md](Indicator-Atr.md) — the volatility measure underneath.
- [Indicators-Overview.md](../../Indicators-Overview.md) — the full taxonomy.