Regression Slope Oscillator
min_range = 10 | max_range = 100 | step = 5 | signal_line = 7 Overview
Regression Slope Oscillator measures directional persistence by fitting straight-line regressions to the log of price over several lookback windows and averaging those slope estimates together. Positive readings show that the selected windows are, on average, climbing at a positive rate, while negative readings show synchronized downside drift.
The indicator also maintains a signal line built from the oscillator itself. From that pairing it derives two discrete marker series: bullish reversals when the oscillator crosses above the signal while still below zero, and bearish reversals when it crosses below the signal while still above zero.
Defaults: `min_range = 10`, `max_range = 100`, `step = 5`, and `signal_line = 7`.
Implementation Examples
Run the oscillator on candle closes or on a raw price slice with one resolved parameter set.
use vector_ta::indicators::regression_slope_oscillator::{
regression_slope_oscillator,
RegressionSlopeOscillatorInput,
RegressionSlopeOscillatorParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
let close = vec![100.0, 100.6, 101.1, 101.8, 102.4, 102.0, 103.3, 104.1];
let output = regression_slope_oscillator(&RegressionSlopeOscillatorInput::from_slice(
&close,
RegressionSlopeOscillatorParams {
min_range: Some(10),
max_range: Some(60),
step: Some(5),
signal_line: Some(7),
},
))?;
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let candle_output =
regression_slope_oscillator(&RegressionSlopeOscillatorInput::with_default_candles(&candles))?;
println!("value = {:?}", output.value.last());
println!("signal = {:?}", candle_output.signal.last());
println!("bullish = {:?}", candle_output.bullish_reversal.last());
println!("bearish = {:?}", candle_output.bearish_reversal.last()); API Reference
Input Methods ▼
RegressionSlopeOscillatorInput::from_candles(&Candles, RegressionSlopeOscillatorParams)
-> RegressionSlopeOscillatorInput
RegressionSlopeOscillatorInput::from_slice(&[f64], RegressionSlopeOscillatorParams)
-> RegressionSlopeOscillatorInput
RegressionSlopeOscillatorInput::with_default_candles(&Candles)
-> RegressionSlopeOscillatorInput Parameters Structure ▼
pub struct RegressionSlopeOscillatorParams {
pub min_range: Option<usize>,
pub max_range: Option<usize>,
pub step: Option<usize>,
pub signal_line: Option<usize>,
} Output Structure ▼
pub struct RegressionSlopeOscillatorOutput {
pub value: Vec<f64>,
pub signal: Vec<f64>,
pub bullish_reversal: Vec<f64>,
pub bearish_reversal: Vec<f64>,
} Validation, Warmup & NaNs ▼
- The input series must be non-empty and must contain at least one finite positive value because the calculation operates on the natural log of price.
min_rangeandmax_rangemust both be at least2,stepmust be greater than0, andsignal_linemust be greater than0.min_rangecannot exceedmax_range, and invalid batch axes produceInvalidRangeerrors.- The oscillator begins producing finite values after the largest regression window has filled. The signal line and reversal markers require that warmup plus the signal-line average.
- Non-finite or non-positive streaming inputs are treated as invalid and yield NaN outputs for the affected update.
- Batch mode rejects unsupported kernels through
InvalidKernelForBatch.
Builder, Streaming & Batch APIs ▼
RegressionSlopeOscillatorBuilder::new()
.min_range(usize)
.max_range(usize)
.step(usize)
.signal_line(usize)
.kernel(Kernel)
.apply(&Candles)
.apply_slice(&[f64])
.into_stream()
RegressionSlopeOscillatorStream::try_new(RegressionSlopeOscillatorParams)
stream.update(f64) -> (f64, f64, f64, f64)
RegressionSlopeOscillatorBatchBuilder::new()
.range(RegressionSlopeOscillatorBatchRange {
min_range: (usize, usize, usize),
max_range: (usize, usize, usize),
step: (usize, usize, usize),
signal_line: (usize, usize, usize),
})
.kernel(Kernel)
.apply(&Candles)
.apply_slice(&[f64]) Error Handling ▼
pub enum RegressionSlopeOscillatorError {
EmptyInputData,
AllValuesInvalidForLog,
InvalidMinRange { min_range: usize },
InvalidMaxRange { max_range: usize },
InvalidStep { step: usize },
InvalidSignalLine { signal_line: usize },
InvalidRangeConfig { min_range: usize, max_range: usize, step: usize },
OutputLengthMismatch { expected: usize, got: usize },
InvalidRange { start: String, end: String, step: String },
InvalidKernelForBatch(Kernel),
} Python Bindings
Python exposes a scalar function, a streaming class, and a batch helper. The scalar call returns four NumPy arrays, the stream emits a four-value tuple on each update, and the batch helper returns flattened matrices plus the resolved parameter combinations and output dimensions.
from vector_ta import (
regression_slope_oscillator,
regression_slope_oscillator_batch,
RegressionSlopeOscillatorStream,
)
value, signal, bullish_reversal, bearish_reversal = regression_slope_oscillator(
close,
min_range=10,
max_range=60,
step=5,
signal_line=7,
kernel="auto",
)
stream = RegressionSlopeOscillatorStream(
min_range=10,
max_range=40,
step=5,
signal_line=6,
)
print(stream.update(close[-1]))
batch = regression_slope_oscillator_batch(
close,
min_range_range=(10, 20, 5),
max_range_range=(40, 80, 20),
step_range=(5, 10, 5),
signal_line_range=(5, 9, 2),
kernel="auto",
)
print(batch["rows"], batch["cols"])
print(batch["min_ranges"]) JavaScript/WASM Bindings
The WASM layer exposes scalar, batch, allocation, and into-buffer entry points. The scalar and batch helpers return plain JS objects containing the oscillator arrays, and the low-level APIs write those arrays into caller-managed memory.
import init, {
regression_slope_oscillator_js,
regression_slope_oscillator_batch_js,
regression_slope_oscillator_alloc,
regression_slope_oscillator_free,
regression_slope_oscillator_into,
regression_slope_oscillator_batch_into,
} from "vector-ta-wasm";
await init();
const out = regression_slope_oscillator_js(close, 10, 60, 5, 7);
console.log(out.value, out.signal);
const batch = regression_slope_oscillator_batch_js(close, {
min_range_range: [10, 20, 5],
max_range_range: [40, 80, 20],
step_range: [5, 10, 5],
signal_line_range: [5, 9, 2],
});
console.log(batch.rows, batch.cols);
console.log(batch.bullish_reversal); 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)