SuperTrend Oscillator

Parameters: length = 10 | mult = 2 | smooth = 72

Overview

SuperTrend Oscillator takes the directional logic of a SuperTrend filter and expresses it as an oscillator rather than as a stop line on the chart. Along with the raw oscillator it also returns a smoothed signal line and a histogram, which makes the study easier to interpret with the same kinds of crossover and momentum tools often used with MACD-style indicators.

In VectorTA the indicator accepts high, low, and source slices or candle data with a chosen source field, supports a streaming state machine for live bars, and exposes batch sweeps across the SuperTrend length, the volatility multiplier, and the smoothing window. That makes it useful for comparing how aggressive or smooth the oscillator should be across different trend-following regimes.

Defaults: `length = 10`, `mult = 2.0`, and `smooth = 72`.

Implementation Examples

Compute the oscillator from explicit high/low/source slices or from candle data.

use vector_ta::indicators::supertrend_oscillator::{
    supertrend_oscillator,
    SuperTrendOscillatorInput,
    SuperTrendOscillatorParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};

let direct = supertrend_oscillator(&SuperTrendOscillatorInput::from_slices(
    &high,
    &low,
    &close,
    SuperTrendOscillatorParams {
        length: Some(10),
        mult: Some(2.0),
        smooth: Some(72),
    },
))?;

let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let from_candles = supertrend_oscillator(
    &SuperTrendOscillatorInput::with_default_candles(&candles),
)?;

println!("latest oscillator = {:?}", direct.oscillator.last());
println!("latest signal = {:?}", direct.signal.last());
println!("latest histogram = {:?}", direct.histogram.last());
println!("candle histogram = {:?}", from_candles.histogram.last());

API Reference

Input Methods
SuperTrendOscillatorInput::from_candles(&Candles, "close", SuperTrendOscillatorParams)
    -> SuperTrendOscillatorInput

SuperTrendOscillatorInput::from_slices(&[f64], &[f64], &[f64], SuperTrendOscillatorParams)
    -> SuperTrendOscillatorInput

SuperTrendOscillatorInput::with_default_candles(&Candles)
    -> SuperTrendOscillatorInput
Parameters Structure
pub struct SuperTrendOscillatorParams {
    pub length: Option<usize>,  // default 10
    pub mult: Option<f64>,      // default 2.0
    pub smooth: Option<usize>,  // default 72
}
Output Structure
pub struct SuperTrendOscillatorOutput {
    pub oscillator: Vec<f64>,
    pub signal: Vec<f64>,
    pub histogram: Vec<f64>,
}
Validation, Warmup & NaNs
  • The high, low, and source slices must have matching lengths and contain enough valid bars for the resolved SuperTrend lookback.
  • length must fit the available data, mult must be finite and valid, and smooth must be a valid positive smoothing window.
  • Direct evaluation rejects empty input, length mismatches, and all-invalid input bars.
  • The stream returns None until it has enough valid bars to seed the SuperTrend and the smoothed signal stage.
  • Output buffers must align with the source length or the indicator returns the documented output-length mismatch error.
  • Batch mode validates all integer and float sweep ranges and rejects non-batch kernels.
Builder, Streaming & Batch APIs
SuperTrendOscillatorBuilder::new()
    .length(usize)
    .mult(f64)
    .smooth(usize)
    .source("close")
    .kernel(Kernel)
    .apply(&Candles)
    .apply_slices(&[f64], &[f64], &[f64])
    .into_stream()

SuperTrendOscillatorStream::try_new(params)
stream.update(high, low, source) -> Option<(f64, f64, f64)>

SuperTrendOscillatorBatchBuilder::new()
    .length_range(start, end, step)
    .mult_range(start, end, step)
    .smooth_range(start, end, step)
    .kernel(Kernel)
    .apply_candles(&Candles)
    .apply_slices(&[f64], &[f64], &[f64])

Python Bindings

Python exposes a direct function, a stream class, and a batch helper that returns oscillator, signal, and histogram matrices plus the resolved length, multiplier, and smoothing axes.

from vector_ta import (
    supertrend_oscillator,
    supertrend_oscillator_batch,
    SuperTrendOscillatorStream,
)

oscillator, signal, histogram = supertrend_oscillator(
    high,
    low,
    close,
    length=10,
    mult=2.0,
    smooth=72,
)

stream = SuperTrendOscillatorStream(length=10, mult=2.0, smooth=72)
point = stream.update(high[-1], low[-1], close[-1])

batch = supertrend_oscillator_batch(
    high,
    low,
    close,
    length_range=(8, 14, 2),
    mult_range=(1.5, 3.0, 0.5),
    smooth_range=(36, 72, 18),
)

print(batch["oscillator"].shape)
print(batch["mult_range"])

JavaScript/WASM Bindings

The WASM layer exposes direct single and batch calls along with host and raw-pointer into-buffer entry points for low-overhead consumers.

import init, {
  supertrend_oscillator,
  supertrend_oscillator_batch,
  supertrend_oscillator_alloc,
  supertrend_oscillator_free,
  supertrend_oscillator_into,
  supertrend_oscillator_into_host,
  supertrend_oscillator_batch_into,
} from "vector-ta-wasm";

await init();

const single = supertrend_oscillator(high, low, close, 10, 2.0, 72);
console.log(single.oscillator, single.signal, single.histogram);

const batch = supertrend_oscillator_batch(high, low, close, {
  length_range: [8, 14, 2],
  mult_range: [1.5, 3.0, 0.5],
  smooth_range: [36, 72, 18],
});

const ptr = supertrend_oscillator_alloc(close.length * 3);
supertrend_oscillator_into_host(high, low, close, ptr, 10, 2.0, 72);
supertrend_oscillator_free(ptr, close.length * 3);

CUDA Bindings (Rust)

Additional details for the CUDA bindings can be found inside the VectorTA repository.

Performance Analysis

Comparison:
View:
Placeholder data (no recorded benchmarks for this indicator)

Across sizes, Rust CPU runs about 1.14× faster than Tulip C in this benchmark.

Loading chart...

AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU)

Related Indicators