Possible RSI
period = 32 | rsi_mode = regular | norm_period = 100 | normalization_mode = gaussian_fisher | normalization_length = 15 | nonlag_period = 15 | dynamic_zone_period = 20 | buy_probability = 0.2 | sell_probability = 0.2 | signal_type = zeroline_crossover | run_highpass = | highpass_period = 15 Overview
Possible RSI is a layered oscillator. It begins with an RSI-family engine such as regular RSI or RSX, optionally filters the source first with a high-pass stage, then normalizes the result into a bounded probability-style oscillator using one of several normalization pipelines.
From that normalized value it derives dynamic buy, sell, and middle levels, a state series, and long or short signals according to the selected trigger mode. The stream version exposes the full seven-field point output and reports its own warmup period from the resolved parameter set.
Defaults: `period = 32`, `rsi_mode = "regular"`, `norm_period = 100`, `normalization_mode = "gaussian_fisher"`, `normalization_length = 15`, `nonlag_period = 15`, `dynamic_zone_period = 20`, `buy_probability = 0.2`, `sell_probability = 0.2`, `signal_type = "zeroline_crossover"`, `run_highpass = false`, and `highpass_period = 15`.
Implementation Examples
Run the indicator on candle closes or on a direct slice with one resolved parameter set.
use vector_ta::indicators::possible_rsi::{
possible_rsi,
PossibleRsiInput,
PossibleRsiParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
let output = possible_rsi(&PossibleRsiInput::from_slice(
&close,
PossibleRsiParams {
period: Some(32),
rsi_mode: Some("regular".to_string()),
norm_period: Some(100),
normalization_mode: Some("gaussian_fisher".to_string()),
normalization_length: Some(15),
nonlag_period: Some(15),
dynamic_zone_period: Some(20),
buy_probability: Some(0.2),
sell_probability: Some(0.2),
signal_type: Some("zeroline_crossover".to_string()),
run_highpass: Some(false),
highpass_period: Some(15),
},
))?;
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let candle_output = possible_rsi(&PossibleRsiInput::with_default_candles(&candles))?;
println!("value = {:?}", output.value.last());
println!("long signal = {:?}", candle_output.long_signal.last()); API Reference
Input Methods ▼
PossibleRsiInput::from_candles(&Candles, "close", PossibleRsiParams)
-> PossibleRsiInput
PossibleRsiInput::from_slice(&[f64], PossibleRsiParams)
-> PossibleRsiInput
PossibleRsiInput::with_default_candles(&Candles)
-> PossibleRsiInput Parameters Structure ▼
pub struct PossibleRsiParams {
pub period: Option<usize>, // default 32
pub rsi_mode: Option<String>, // regular, rsx, slow, rapid, harris, cutler, ehlers_smoothed
pub norm_period: Option<usize>, // default 100
pub normalization_mode: Option<String>, // gaussian_fisher, softmax, regular_norm
pub normalization_length: Option<usize>, // default 15
pub nonlag_period: Option<usize>, // default 15
pub dynamic_zone_period: Option<usize>, // default 20
pub buy_probability: Option<f64>, // default 0.2
pub sell_probability: Option<f64>, // default 0.2
pub signal_type: Option<String>, // slope, dynamic_middle_crossover, levels_crossover, zeroline_crossover
pub run_highpass: Option<bool>, // default false
pub highpass_period: Option<usize>, // default 15
} Output Structure ▼
pub struct PossibleRsiOutput {
pub value: Vec<f64>,
pub buy_level: Vec<f64>,
pub sell_level: Vec<f64>,
pub middle_level: Vec<f64>,
pub state: Vec<f64>,
pub long_signal: Vec<f64>,
pub short_signal: Vec<f64>,
} Validation, Warmup & Modes ▼
- The input slice must not be empty and must contain at least one finite value.
period,norm_period,normalization_length,nonlag_period,dynamic_zone_period, andhighpass_periodmust all be greater than0.buy_probabilityandsell_probabilitymust be finite and remain inside[0.0, 0.5].- The supported RSI modes are
regular,rsx,slow,rapid,harris,cutler, andehlers_smoothed. - The supported normalization modes are
gaussian_fisher,softmax, andregular_norm. - The supported signal types are
slope,dynamic_middle_crossover,levels_crossover, andzeroline_crossover. - The resolved warmup is derived from
period,norm_period,normalization_length, the nonlag kernel length, anddynamic_zone_period; the direct path requires one more valid bar than that estimate. - Batch mode validates every numeric sweep axis and rejects non-batch kernels.
Builder, Streaming & Batch APIs ▼
PossibleRsiBuilder::new()
.period(usize)
.rsi_mode("regular")
.norm_period(usize)
.normalization_mode("gaussian_fisher")
.normalization_length(usize)
.nonlag_period(usize)
.dynamic_zone_period(usize)
.buy_probability(f64)
.sell_probability(f64)
.signal_type("zeroline_crossover")
.run_highpass(bool)
.highpass_period(usize)
.kernel(Kernel)
.apply(&Candles)
.apply_slice(&[f64])
.into_stream()
PossibleRsiStream::try_new(params)
stream.update(f64) -> Option<PossibleRsiPoint>
stream.reset()
stream.get_warmup_period() -> usize
PossibleRsiBatchBuilder::new()
.period_range(start, end, step)
.norm_period_range(start, end, step)
.normalization_length_range(start, end, step)
.nonlag_period_range(start, end, step)
.dynamic_zone_period_range(start, end, step)
.buy_probability_range(start, end, step)
.sell_probability_range(start, end, step)
.highpass_period_range(start, end, step)
.kernel(Kernel)
.apply_slice(&[f64]) Python Bindings
Python exposes a scalar function, a stream class, and a batch helper. The scalar call returns seven NumPy arrays,
the stream emits a seven-value tuple or None, and the batch helper returns reshaped matrices plus the
swept numeric axes.
from vector_ta import possible_rsi, possible_rsi_batch, PossibleRsiStream
value, buy_level, sell_level, middle_level, state, long_signal, short_signal = possible_rsi(
close,
period=32,
rsi_mode="regular",
norm_period=100,
normalization_mode="gaussian_fisher",
normalization_length=15,
nonlag_period=15,
dynamic_zone_period=20,
buy_probability=0.2,
sell_probability=0.2,
signal_type="zeroline_crossover",
run_highpass=False,
highpass_period=15,
)
stream = PossibleRsiStream()
point = stream.update(close[-1])
batch = possible_rsi_batch(
close,
period_range=(24, 32, 8),
norm_period_range=(80, 120, 20),
normalization_length_range=(10, 20, 5),
nonlag_period_range=(10, 20, 5),
dynamic_zone_period_range=(16, 24, 8),
buy_probability_range=(0.1, 0.2, 0.1),
sell_probability_range=(0.1, 0.2, 0.1),
)
print(batch.keys()) JavaScript/WASM Bindings
The WASM layer exposes scalar and batch helpers plus low-level allocation and into-buffer APIs. The high-level calls return plain JS objects containing all seven output arrays, and the low-level APIs write those arrays into caller-managed memory.
import init, {
possible_rsi_js,
possible_rsi_batch_js,
possible_rsi_alloc,
possible_rsi_free,
possible_rsi_into,
possible_rsi_batch_into,
} from "vector-ta-wasm";
await init();
const out = possible_rsi_js(
close,
32,
"regular",
100,
"gaussian_fisher",
15,
15,
20,
0.2,
0.2,
"zeroline_crossover",
false,
15,
);
const batch = possible_rsi_batch_js(close, {
period_range: [24, 32, 8],
norm_period_range: [80, 120, 20],
normalization_length_range: [10, 20, 5],
nonlag_period_range: [10, 20, 5],
dynamic_zone_period_range: [16, 24, 8],
buy_probability_range: [0.1, 0.2, 0.1],
sell_probability_range: [0.1, 0.2, 0.1],
}); 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)