SuperTrend
period = 10 | factor = 3 (1–5) Overview
SuperTrend creates a volatility-adjusted trend following overlay by constructing dynamic support and resistance bands around the mid-price. The algorithm calculates the average of high and low prices (HL2), then adds and subtracts a multiple of Average True Range (ATR) to form preliminary upper and lower bands. These bands tighten progressively as they compare against previous values, preventing premature trend reversals. The indicator tracks which band is active based on price position, switching from bullish to bearish only when price definitively crosses the opposing band. When price trades above the lower band, SuperTrend displays that band as support and signals an uptrend; when price falls below the upper band, it flips to show resistance and signals a downtrend. This binary trend state combined with change signals makes SuperTrend popular for mechanical trading systems. The default factor of 3.0 with a 10-period ATR balances noise filtering against responsiveness, though aggressive traders often reduce the factor while conservative approaches increase it.
Implementation Examples
Compute SuperTrend from OHLC arrays or candles:
use vectorta::indicators::supertrend::{supertrend, SuperTrendInput, SuperTrendParams};
use vectorta::utilities::data_loader::{Candles, read_candles_from_csv};
// Using OHLC slices
let high = vec![101.2, 102.6, 103.1, 101.8, 100.9];
let low = vec![ 99.8, 100.7, 101.4, 99.9, 99.6];
let close = vec![100.5, 102.1, 101.9, 100.8, 100.2];
let params = SuperTrendParams { period: Some(10), factor: Some(3.0) };
let input = SuperTrendInput::from_slices(&high, &low, &close, params);
let output = supertrend(&input)?;
// Using Candles with defaults (period=10, factor=3.0)
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let input = SuperTrendInput::with_default_candles(&candles);
let output = supertrend(&input)?;
// Access fields
for (i, t) in output.trend.iter().enumerate() {
let flipped = output.changed[i] == 1.0;
println!("trend[{i}]={t:.4}, changed={flipped}");
} API Reference
Input Methods ▼
// From OHLC slices
SuperTrendInput::from_slices(&[f64], &[f64], &[f64], SuperTrendParams) -> SuperTrendInput
// From candles
SuperTrendInput::from_candles(&Candles, SuperTrendParams) -> SuperTrendInput
// From candles with defaults (period=10, factor=3.0)
SuperTrendInput::with_default_candles(&Candles) -> SuperTrendInput Parameters Structure ▼
pub struct SuperTrendParams {
pub period: Option<usize>, // Default: 10
pub factor: Option<f64>, // Default: 3.0
} Output Structure ▼
pub struct SuperTrendOutput {
pub trend: Vec<f64>, // Active band as trend line (support/resistance)
pub changed: Vec<f64>, // 1.0 when trend flips at t, else 0.0
} Validation, Warmup & NaNs ▼
- Inputs are
high,low,closewith equal length; candles are supported. period > 0andperiod ≤ len; otherwiseSuperTrendError::InvalidPeriod.- If all points are
NaN,SuperTrendError::AllValuesNaN. - Requires at least
periodvalid points after the first finite input; elseNotEnoughValidData. - Warmup: indices before
first_valid + period − 1areNaN; after that,trend/changedare computed. - Streaming returns
Noneuntil internal buffers are filled; thereafter returns(trend, changed)each update. - WASM into-APIs validate output slice lengths; mismatch raises
OutputLengthMismatch.
Error Handling ▼
use vectorta::indicators::supertrend::SuperTrendError;
match supertrend(&input) {
Ok(out) => use_output(out),
Err(SuperTrendError::EmptyData) => eprintln!("empty input"),
Err(SuperTrendError::AllValuesNaN) => eprintln!("all values are NaN"),
Err(SuperTrendError::InvalidPeriod { period, data_len }) =>
eprintln!("invalid period {period} for len {data_len}"),
Err(SuperTrendError::NotEnoughValidData { needed, valid }) =>
eprintln!("need {needed} valid points, only {valid}"),
Err(SuperTrendError::OutputLengthMismatch { expected, got }) =>
eprintln!("output len {got}, expected {expected}"),
Err(SuperTrendError::AtrError(e)) => eprintln!("ATR error: {e}"),
} Python Bindings
Basic Usage ▼
Calculate SuperTrend with NumPy arrays (returns trend and changed):
import numpy as np
from vectorta import supertrend
high = np.array([101.2, 102.6, 103.1, 101.8, 100.9], dtype=np.float64)
low = np.array([ 99.8, 100.7, 101.4, 99.9, 99.6], dtype=np.float64)
close= np.array([100.5, 102.1, 101.9, 100.8, 100.2], dtype=np.float64)
trend, changed = supertrend(high, low, close, period=10, factor=3.0, kernel="auto")
print(trend.shape, changed.shape) Streaming Real-time Updates ▼
Use the dedicated stream class (warmup returns None):
from vectorta import SuperTrendStream
stream = SuperTrendStream(10, 3.0)
val = stream.update(101.2, 99.8, 100.5)
if val is not None:
trend, changed = val
if changed == 1.0:
print("trend flipped") Batch Parameter Optimization ▼
Calculate multiple period/factor combinations at once:
import numpy as np
from vectorta import supertrend_batch
high = np.array([...], dtype=np.float64)
low = np.array([...], dtype=np.float64)
close = np.array([...], dtype=np.float64)
res = supertrend_batch(
high,
low,
close,
period_range=(5, 20, 5),
factor_range=(2.0, 4.0, 0.5),
kernel="auto"
)
# res['trend'] and res['changed'] are shaped [rows, len]
print(res['periods'], res['factors']) CUDA Acceleration ▼
CUDA support for SuperTrend is coming soon. The API will follow the same pattern as other CUDA-enabled indicators.
# Coming soon: CUDA-accelerated SuperTrend calculations JavaScript/WASM Bindings
Basic Usage ▼
Compute SuperTrend from Float64Array inputs:
import { supertrend_js } from 'vectorta-wasm';
const high = new Float64Array([/* ... */]);
const low = new Float64Array([/* ... */]);
const close= new Float64Array([/* ... */]);
const res = supertrend_js(high, low, close, 10, 3.0);
// res: { values: Float64Array, rows: 2, cols: N }
const { values, rows, cols } = res as any;
// First row = trend, second row = changed
const trend = values.slice(0, cols);
const changed = values.slice(cols, 2 * cols);
console.log(trend, changed); Memory-Efficient Operations ▼
Use the *_alloc/free and *_into functions for zero-copy results:
import { supertrend_alloc, supertrend_free, supertrend_into, memory } from 'vectorta-wasm';
const N = close.length;
const trendPtr = supertrend_alloc(N);
const changedPtr = supertrend_alloc(N);
// Assume highPtr/lowPtr/closePtr already created or use views to pass JS arrays directly
supertrend_into(highPtr, lowPtr, closePtr, trendPtr, changedPtr, N, 10, 3.0);
const trend = new Float64Array(memory.buffer, trendPtr, N).slice();
const changed = new Float64Array(memory.buffer, changedPtr, N).slice();
supertrend_free(trendPtr, N);
supertrend_free(changedPtr, N); Batch Processing ▼
Test multiple combinations using the WASM batch API:
import { supertrend_batch_js } from 'vectorta-wasm';
const config = { period_range: [5, 20, 5], factor_range: [2.0, 4.0, 0.5] };
const out = supertrend_batch_js(high, low, close, config);
// out: { values, periods, factors, rows: 2*combos, cols }
// For each combo i, rows 2*i and 2*i+1 are trend/changed
const { values, periods, factors, rows, cols } = out as any; Performance Analysis
AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU) | Benchmarks: 2026-01-05
Related Indicators
Average Directional Index
Technical analysis indicator
Average Directional Movement Index Rating
Technical analysis indicator
Alligator
Technical analysis indicator
Aroon
Technical analysis indicator
Aroon Oscillator
Technical analysis indicator
Chande Momentum Oscillator
Technical analysis indicator