Range Filtered Trend Signals
kalman_alpha = 0.01 | kalman_beta = 0.1 | kalman_period = 77 | dev = 1.2 | supertrend_factor = 0.7 | supertrend_atr_period = 7 Overview
Range Filtered Trend Signals combines a Kalman-based trend estimate, a supertrend-style envelope, and a long weighted moving average filter to label whether the market is currently trending or ranging. Instead of only producing one oscillator line, it returns the filter backbone, the active envelope, trend-state flags, and short- versus long-term directional markers.
That makes it useful when you want the raw smoothed trend estimate, the active supertrend level, and the regime classification from the same indicator family. VectorTA supports high-low-close candle input, raw slices, live streaming updates, and full batch sweeps across all six numeric controls.
Defaults: `kalman_alpha = 0.01`, `kalman_beta = 0.1`, `kalman_period = 77`, `dev = 1.2`, `supertrend_factor = 0.7`, and `supertrend_atr_period = 7`.
Implementation Examples
Run the filter stack from candles or from explicit high, low, and close slices.
use vector_ta::indicators::range_filtered_trend_signals::{
range_filtered_trend_signals,
RangeFilteredTrendSignalsInput,
RangeFilteredTrendSignalsParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
let direct = range_filtered_trend_signals(&RangeFilteredTrendSignalsInput::from_slices(
&high,
&low,
&close,
RangeFilteredTrendSignalsParams::default(),
))?;
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let from_candles = range_filtered_trend_signals(&RangeFilteredTrendSignalsInput::with_default_candles(&candles))?;
println!("kalman = {:?}", direct.kalman.last());
println!("market_trending = {:?}", from_candles.market_trending.last());API Reference
Input Methods▼
RangeFilteredTrendSignalsInput::from_candles(&Candles, RangeFilteredTrendSignalsParams)
-> RangeFilteredTrendSignalsInput
RangeFilteredTrendSignalsInput::from_slices(&[f64], &[f64], &[f64], RangeFilteredTrendSignalsParams)
-> RangeFilteredTrendSignalsInput
RangeFilteredTrendSignalsInput::with_default_candles(&Candles)
-> RangeFilteredTrendSignalsInputParameters Structure▼
pub struct RangeFilteredTrendSignalsParams {
pub kalman_alpha: Option<f64>,
pub kalman_beta: Option<f64>,
pub kalman_period: Option<usize>,
pub dev: Option<f64>,
pub supertrend_factor: Option<f64>,
pub supertrend_atr_period: Option<usize>,
}Output Structure▼
pub struct RangeFilteredTrendSignalsOutput {
pub kalman: Vec<f64>,
pub supertrend: Vec<f64>,
pub upper_band: Vec<f64>,
pub lower_band: Vec<f64>,
pub trend: Vec<f64>,
pub kalman_trend: Vec<f64>,
pub state: Vec<f64>,
pub market_trending: Vec<f64>,
pub market_ranging: Vec<f64>,
pub short_term_bullish: Vec<f64>,
pub short_term_bearish: Vec<f64>,
pub long_term_bullish: Vec<f64>,
pub long_term_bearish: Vec<f64>,
}Validation & Warmup▼
- High, low, and close series must be non-empty, equal in length, and contain at least one valid triple.
kalman_alphamust be finite and greater than0.kalman_betamust be finite and non-negative.kalman_periodandsupertrend_atr_periodmust be greater than0.- The vector path has a long warmup driven by the internal 200-period weighted average and the ATR period.
- Batch mode validates every sweep axis and rejects non-batch kernels.
Builder, Streaming & Batch APIs▼
RangeFilteredTrendSignalsBuilder::new()
.kalman_alpha(f64)
.kalman_beta(f64)
.kalman_period(usize)
.dev(f64)
.supertrend_factor(f64)
.supertrend_atr_period(usize)
.kernel(Kernel)
.apply(&Candles)
.apply_slices(&[f64], &[f64], &[f64])
.into_stream()
RangeFilteredTrendSignalsStream::try_new(params)
stream.update(high, low, close) -> Option<RangeFilteredTrendSignalsStreamOutput>
RangeFilteredTrendSignalsBatchBuilder::new()
.range(RangeFilteredTrendSignalsBatchRange)
.kernel(Kernel)
.apply(&Candles)
.apply_slices(&[f64], &[f64], &[f64])Python Bindings
Python exposes scalar and batch helpers that return dictionaries keyed by every output field, plus a stream class that returns the current multi-field signal snapshot once the filter state is ready.
from vector_ta import (
range_filtered_trend_signals,
range_filtered_trend_signals_batch,
RangeFilteredTrendSignalsStream,
)
single = range_filtered_trend_signals(high, low, close)
stream = RangeFilteredTrendSignalsStream()
point = stream.update(high[-1], low[-1], close[-1])
batch = range_filtered_trend_signals_batch(
high,
low,
close,
kalman_alpha_range=(0.01, 0.02, 0.01),
kalman_beta_range=(0.1, 0.2, 0.1),
kalman_period_range=(77, 99, 22),
dev_range=(1.0, 1.4, 0.2),
supertrend_factor_range=(0.7, 1.1, 0.2),
supertrend_atr_period_range=(7, 11, 2),
)
print(single["kalman"][-1], single["market_trending"][-1])
print(batch["rows"], batch["cols"])JavaScript/WASM Bindings
The WASM layer exposes object-returning scalar and batch helpers covering all output fields for the filter stack.
import init, {
range_filtered_trend_signals_js,
range_filtered_trend_signals_batch,
} from "vector-ta-wasm";
await init();
const single = range_filtered_trend_signals_js(
high,
low,
close,
0.01,
0.1,
77,
1.2,
0.7,
7,
);
const batch = range_filtered_trend_signals_batch(high, low, close, {
kalman_alpha_range: [0.01, 0.02, 0.01],
kalman_beta_range: [0.1, 0.2, 0.1],
kalman_period_range: [77, 99, 22],
dev_range: [1.0, 1.4, 0.2],
supertrend_factor_range: [0.7, 1.1, 0.2],
supertrend_atr_period_range: [7, 11, 2],
});
console.log(single.kalman, single.market_trending, batch.rows);CUDA Bindings (Rust)
Additional details for the CUDA bindings can be found inside the VectorTA repository.
Performance Analysis
Across sizes, Rust CPU runs about 1.14× faster than Tulip C in this benchmark.
AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU)