Stochastic Connors RSI

Parameters: stoch_length = 3 | smooth_k = 3 | smooth_d = 3 | rsi_length = 3 | updown_length = 2 | roc_length = 100

Overview

Stochastic Connors RSI starts with the three-part Connors RSI idea, then measures that composite inside a short stochastic window and smooths the result into a K and D pair. The output stays in oscillator form, but it reacts to a broader set of momentum cues than a basic stochastic RSI because it also accounts for streak behavior and a longer rate-of-change ranking component.

In VectorTA the indicator works on a single source series or on candle data with an explicit source field, supports a streaming state machine with both plain and reset-on-NaN updates, and exposes batch sweeps across all six length controls. That makes it suitable for both compact tactical oscillators and larger parameter studies.

Defaults: `stoch_length = 3`, `smooth_k = 3`, `smooth_d = 3`, `rsi_length = 3`, `updown_length = 2`, and `roc_length = 100`.

Implementation Examples

Run the indicator on a direct source slice or on candle data with an explicit field.

use vector_ta::indicators::stochastic_connors_rsi::{
    stochastic_connors_rsi,
    StochasticConnorsRsiInput,
    StochasticConnorsRsiParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};

let direct = stochastic_connors_rsi(&StochasticConnorsRsiInput::from_slice(
    &close,
    StochasticConnorsRsiParams {
        stoch_length: Some(3),
        smooth_k: Some(3),
        smooth_d: Some(3),
        rsi_length: Some(3),
        updown_length: Some(2),
        roc_length: Some(100),
    },
))?;

let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let from_candles = stochastic_connors_rsi(&StochasticConnorsRsiInput::from_candles(
    &candles,
    "close",
    StochasticConnorsRsiParams::default(),
))?;

println!("latest k = {:?}", direct.k.last());
println!("latest d = {:?}", direct.d.last());
println!("candle d = {:?}", from_candles.d.last());

API Reference

Input Methods
StochasticConnorsRsiInput::from_candles(&Candles, "close", StochasticConnorsRsiParams)
    -> StochasticConnorsRsiInput

StochasticConnorsRsiInput::from_slice(&[f64], StochasticConnorsRsiParams)
    -> StochasticConnorsRsiInput

StochasticConnorsRsiInput::with_default_candles(&Candles)
    -> StochasticConnorsRsiInput
Parameters Structure
pub struct StochasticConnorsRsiParams {
    pub stoch_length: Option<usize>,   // default 3
    pub smooth_k: Option<usize>,       // default 3
    pub smooth_d: Option<usize>,       // default 3
    pub rsi_length: Option<usize>,     // default 3
    pub updown_length: Option<usize>,  // default 2
    pub roc_length: Option<usize>,     // default 100
}
Output Structure
pub struct StochasticConnorsRsiOutput {
    pub k: Vec<f64>,
    pub d: Vec<f64>,
}
Validation, Warmup & NaNs
  • The input source slice must not be empty or entirely NaN, and every resolved length must fit the available data.
  • stoch_length, smooth_k, smooth_d, rsi_length, updown_length, and roc_length must all be greater than zero.
  • Direct evaluation reports the specific invalid-length error for whichever axis exceeds the usable data length.
  • The normal stream update assumes continuous data, while update_reset_on_nan explicitly resets state when gaps appear.
  • Output buffers must align with the source length or the indicator returns the documented output-length mismatch error.
  • Batch mode validates all sweep ranges and parameter combinations before computing the K and D matrices.
Builder, Streaming & Batch APIs
StochasticConnorsRsiBuilder::new()
    .stoch_length(usize)
    .smooth_k(usize)
    .smooth_d(usize)
    .rsi_length(usize)
    .updown_length(usize)
    .roc_length(usize)
    .source("close")
    .kernel(Kernel)
    .apply(&Candles)
    .apply_slice(&[f64])
    .into_stream()

StochasticConnorsRsiStream::try_new(params)
stream.update(value) -> Option<(f64, f64)>
stream.update_reset_on_nan(value) -> Option<(f64, f64)>

StochasticConnorsRsiBatchBuilder::new()
    .stoch_length_range(start, end, step)
    .smooth_k_range(start, end, step)
    .smooth_d_range(start, end, step)
    .rsi_length_range(start, end, step)
    .updown_length_range(start, end, step)
    .roc_length_range(start, end, step)
    .apply_slice(&[f64])
    .apply_candles(&Candles, "close")

Python Bindings

Python exposes a direct function, a stream class that already uses the reset-on-NaN update behavior, and a batch helper that returns the K and D matrices plus the resolved length axes.

from vector_ta import (
    stochastic_connors_rsi,
    stochastic_connors_rsi_batch,
    StochasticConnorsRsiStream,
)

k, d = stochastic_connors_rsi(
    close,
    stoch_length=3,
    smooth_k=3,
    smooth_d=3,
    rsi_length=3,
    updown_length=2,
    roc_length=100,
)

stream = StochasticConnorsRsiStream(
    stoch_length=3,
    smooth_k=3,
    smooth_d=3,
    rsi_length=3,
    updown_length=2,
    roc_length=100,
)
point = stream.update(close[-1])

batch = stochastic_connors_rsi_batch(
    close,
    stoch_length_range=(3, 5, 1),
    smooth_k_range=(2, 4, 1),
    smooth_d_range=(2, 4, 1),
    rsi_length_range=(3, 5, 1),
    updown_length_range=(2, 3, 1),
    roc_length_range=(50, 100, 25),
)

print(batch["k"].shape)
print(batch["roc_lengths"])

JavaScript/WASM Bindings

The WASM layer exposes object-returning single and batch calls plus low-level allocation and into-buffer entry points for memory-sensitive consumers.

import init, {
  stochastic_connors_rsi_js,
  stochastic_connors_rsi_batch_js,
  stochastic_connors_rsi_alloc,
  stochastic_connors_rsi_free,
  stochastic_connors_rsi_into,
  stochastic_connors_rsi_into_host,
  stochastic_connors_rsi_batch_into,
} from "vector-ta-wasm";

await init();

const single = stochastic_connors_rsi_js(close, 3, 3, 3, 3, 2, 100);
console.log(single.k, single.d);

const batch = stochastic_connors_rsi_batch_js(close, {
  stoch_length_range: [3, 5, 1],
  smooth_k_range: [2, 4, 1],
  smooth_d_range: [2, 4, 1],
  rsi_length_range: [3, 5, 1],
  updown_length_range: [2, 3, 1],
  roc_length_range: [50, 100, 25],
});

const ptr = stochastic_connors_rsi_alloc(close.length * 2);
stochastic_connors_rsi_into_host(close, ptr, 3, 3, 3, 3, 2, 100);
stochastic_connors_rsi_free(ptr, close.length * 2);

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