Adaptive Bounds RSI
rsi_length = 14 | alpha = 0.1 Overview
Adaptive Bounds RSI starts with a conventional RSI calculation and then wraps that oscillator in a set of five moving guide levels. Instead of keeping the levels fixed at static overbought and oversold zones, the indicator shifts each level toward the nearest observed RSI state using an adaptive step. That produces a structure of lower bound, lower mid, center, upper mid, and upper bound that can expand, contract, and re-center as market behavior changes.
The result is more than a single oscillator line. You get the RSI itself, the adaptive band structure, a regime classification from deeply oversold to strongly overbought, regime-flip markers when the neutral state is abandoned, and one-shot lower and upper trigger signals when RSI crosses the outer adaptive bounds. That makes the indicator useful both for regime tracking and for detecting fresh excursions into adaptive extremes.
Defaults: Adaptive Bounds RSI uses `rsi_length = 14` and `alpha = 0.1`.
Implementation Examples
Compute the adaptive RSI structure from a slice or from a candle source field.
use vector_ta::indicators::adaptive_bounds_rsi::{
adaptive_bounds_rsi,
AdaptiveBoundsRsiInput,
AdaptiveBoundsRsiParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
let close = vec![100.0, 101.1, 102.0, 101.7, 102.8, 103.5, 102.9, 103.8];
let output = adaptive_bounds_rsi(&AdaptiveBoundsRsiInput::from_slice(
&close,
AdaptiveBoundsRsiParams {
rsi_length: Some(14),
alpha: Some(0.1),
},
))?;
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let candle_output = adaptive_bounds_rsi(
&AdaptiveBoundsRsiInput::with_default_candles(&candles)
)?;
println!("Latest RSI: {:?}", output.rsi.last());
println!("Latest regime: {:?}", output.regime.last());
println!("Latest upper signal: {:?}", candle_output.upper_signal.last()); API Reference
Input Methods ▼
// From candles and a named source field
AdaptiveBoundsRsiInput::from_candles(&Candles, &str, AdaptiveBoundsRsiParams)
-> AdaptiveBoundsRsiInput
// From a slice
AdaptiveBoundsRsiInput::from_slice(&[f64], AdaptiveBoundsRsiParams)
-> AdaptiveBoundsRsiInput
// From candles with default parameters
AdaptiveBoundsRsiInput::with_default_candles(&Candles)
-> AdaptiveBoundsRsiInput Parameters Structure ▼
pub struct AdaptiveBoundsRsiParams {
pub rsi_length: Option<usize>, // default 14
pub alpha: Option<f64>, // default 0.1
} Output Structure ▼
pub struct AdaptiveBoundsRsiOutput {
pub rsi: Vec<f64>,
pub lower_bound: Vec<f64>,
pub lower_mid: Vec<f64>,
pub mid: Vec<f64>,
pub upper_mid: Vec<f64>,
pub upper_bound: Vec<f64>,
pub regime: Vec<f64>,
pub regime_flip: Vec<f64>,
pub lower_signal: Vec<f64>,
pub upper_signal: Vec<f64>,
} Validation, Warmup & NaNs ▼
- The input series must be non-empty and contain at least one finite value.
rsi_lengthmust be greater than zero and no larger than the data length.alphamust be finite and lie within0.001to1.0.- The indicator needs at least
rsi_length + 1valid values after the first finite sample to seed the RSI state. - Warmup lasts until
first_valid_index + rsi_length. Before that point all outputs remainNaN. - Non-finite values reset the streaming RSI state and the adaptive regime state.
- Batch mode accepts only batch-capable kernels, and invalid integer or floating-point ranges return
InvalidRange.
Builder, Streaming & Batch APIs ▼
// Builder
AdaptiveBoundsRsiBuilder::new()
.rsi_length(usize)
.alpha(f64)
.kernel(Kernel)
.apply_slice(&[f64])
AdaptiveBoundsRsiBuilder::new()
.apply(&Candles)
AdaptiveBoundsRsiBuilder::new()
.into_stream()
// Stream
AdaptiveBoundsRsiStream::try_new(AdaptiveBoundsRsiParams)
AdaptiveBoundsRsiStream::update(f64) -> Option<AdaptiveBoundsRsiStreamOutput>
// Batch
AdaptiveBoundsRsiBatchBuilder::new()
.range(AdaptiveBoundsRsiBatchRange)
.kernel(Kernel)
.apply_slice(&[f64])
AdaptiveBoundsRsiBatchBuilder::new()
.apply(&Candles) Error Handling ▼
pub enum AdaptiveBoundsRsiError {
EmptyInputData,
AllValuesNaN,
InvalidRsiLength { rsi_length: usize, data_len: usize },
InvalidAlpha { alpha: f64 },
NotEnoughValidData { needed: usize, valid: usize },
OutputLengthMismatch { expected: usize, got: usize },
InvalidRange { start: String, end: String, step: String },
InvalidKernelForBatch(Kernel),
} Python Bindings
Python exposes a dictionary-returning single-run function, a batch function, and a streaming class. The
single-run binding returns NumPy arrays for all ten output families. Batch returns the same ten matrix outputs
plus the tested rsi_lengths, alphas, and the final
rows and cols shape. The stream returns a ten-value tuple once the RSI core is ready.
import numpy as np
from vector_ta import (
adaptive_bounds_rsi,
adaptive_bounds_rsi_batch,
AdaptiveBoundsRsiStream,
)
data = np.asarray(close_values, dtype=np.float64)
result = adaptive_bounds_rsi(
data,
rsi_length=14,
alpha=0.1,
kernel="auto",
)
print(result["rsi"][-1], result["upper_bound"][-1], result["regime"][-1])
batch = adaptive_bounds_rsi_batch(
data,
rsi_length_range=(10, 14, 2),
alpha_range=(0.08, 0.12, 0.02),
kernel="auto",
)
stream = AdaptiveBoundsRsiStream(14, 0.1)
print(stream.update(data[-1])) JavaScript/WASM Bindings
The WASM layer exposes one object-returning function for normal runs and one for batch sweeps. Both return the full ten-series output surface. The batch path also returns the tested RSI lengths, alphas, and the final matrix shape so the flattened arrays can be reconstructed on the host side.
import init, {
adaptive_bounds_rsi_js,
adaptive_bounds_rsi_batch,
} from "/pkg/vector_ta.js";
await init();
const data = new Float64Array(closeValues);
const result = adaptive_bounds_rsi_js(data, 14, 0.1);
console.log(result.rsi, result.lower_bound, result.upper_bound, result.regime);
const batch = adaptive_bounds_rsi_batch(data, {
rsi_length_range: [10, 14, 2],
alpha_range: [0.08, 0.12, 0.02],
});
console.log(batch.rsi_lengths, batch.alphas, batch.rows, batch.cols); 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)
Related Indicators
Acceleration Oscillator
Technical analysis indicator
Accumulation/Distribution
Technical analysis indicator
Awesome Oscillator
Technical analysis indicator
Absolute Price Oscillator
Technical analysis indicator
Commodity Channel Index
Technical analysis indicator
CCI Cycle
Technical analysis indicator