Regression Slope Oscillator

Parameters: 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_range and max_range must both be at least 2, step must be greater than 0, and signal_line must be greater than 0.
  • min_range cannot exceed max_range, and invalid batch axes produce InvalidRange errors.
  • 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

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