Linear Regression Intensity

Parameters: lookback_period = 12 | range_tolerance = 90 | linreg_length = 90

Overview

Linear Regression Intensity first computes a rolling linear regression over the input series using linreg_length. It then looks at the most recent lookback_period regression values, compares every pair inside that window, and converts the net rising versus falling comparisons into a normalized score between -1.0 and 1.0. Values near 1.0 mean the regression window is broadly ordered upward, values near -1.0 mean it is broadly ordered downward, and values near 0.0 indicate mixed ordering.

The Rust reference supports slice input and candle input. Candle-based usage defaults to the close source. The current implementation validates range_tolerance and carries it through builders, streams, and batch combos, but the compute path in this file does not branch on that parameter.

Defaults: lookback_period = 12, range_tolerance = 90.0, linreg_length = 90, candle source default close.

Implementation Examples

Compute the indicator from a slice or default candle source:

use vector_ta::indicators::linear_regression_intensity::{
    linear_regression_intensity,
    LinearRegressionIntensityInput,
    LinearRegressionIntensityParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};

let data = vec![101.0, 102.5, 103.0, 104.2, 103.8, 105.1, 106.0];
let params = LinearRegressionIntensityParams {
    lookback_period: Some(12),
    range_tolerance: Some(90.0),
    linreg_length: Some(90),
};

let input = LinearRegressionIntensityInput::from_slice(&data, params);
let result = linear_regression_intensity(&input)?;
println!("Latest intensity: {:?}", result.values.last());

let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let input = LinearRegressionIntensityInput::with_default_candles(&candles);
let result = linear_regression_intensity(&input)?;
println!("Candle-based values: {}", result.values.len());

API Reference

Input Methods
LinearRegressionIntensityInput::from_slice(&[f64], LinearRegressionIntensityParams)
LinearRegressionIntensityInput::from_candles(&Candles, source: &str, LinearRegressionIntensityParams)
LinearRegressionIntensityInput::with_default_candles(&Candles) // uses "close"
Parameters Structure
pub struct LinearRegressionIntensityParams {
    pub lookback_period: Option<usize>, // default 12
    pub range_tolerance: Option<f64>,   // default 90.0
    pub linreg_length: Option<usize>,   // default 90
}
  • lookback_period must be at least 1 and cannot exceed the input length.
  • range_tolerance must be finite and between 0.0 and 100.0.
  • linreg_length must be at least 1 and cannot exceed the input length.
  • The current Rust reference validates range_tolerance but does not use it in the scoring computation.
Output Structure
pub struct LinearRegressionIntensityOutput {
    pub values: Vec<f64>,
}

pub struct LinearRegressionIntensityBatchOutput {
    pub values: Vec<f64>,
    pub combos: Vec<LinearRegressionIntensityParams>,
    pub rows: usize,
    pub cols: usize,
}

Batch output is flattened row-major. Each row corresponds to one parameter combo in combos.

Validation, Warmup & NaNs
  • Empty input returns LinearRegressionIntensityError::EmptyInputData.
  • All-NaN input returns LinearRegressionIntensityError::AllValuesNaN.
  • Minimum valid history is linreg_length + lookback_period - 1 non-NaN points after the first valid index.
  • Batch rows inherit the same validation, and non-batch kernels passed to batch APIs return InvalidKernelForBatch.
  • Batch warmup prefix is first_valid_index + linreg_length + lookback_period - 2, filled with NaN.
  • Streaming update returns None until the internal linear regression is ready and the rolling lookback window is full.
  • A non-finite streaming input resets the internal linear-regression stream and comparison window.
Error Handling
use vector_ta::indicators::linear_regression_intensity::{
    linear_regression_intensity,
    LinearRegressionIntensityError,
};

match linear_regression_intensity(&input) {
    Ok(output) => println!("Computed {} values", output.values.len()),
    Err(LinearRegressionIntensityError::EmptyInputData) =>
        eprintln!("Input series is empty"),
    Err(LinearRegressionIntensityError::AllValuesNaN) =>
        eprintln!("Input series contains no finite values"),
    Err(LinearRegressionIntensityError::InvalidLookbackPeriod { lookback_period, data_len }) =>
        eprintln!("Invalid lookback_period {} for data length {}", lookback_period, data_len),
    Err(LinearRegressionIntensityError::InvalidRangeTolerance { range_tolerance }) =>
        eprintln!("Invalid range_tolerance {}", range_tolerance),
    Err(LinearRegressionIntensityError::InvalidLinregLength { linreg_length, data_len }) =>
        eprintln!("Invalid linreg_length {} for data length {}", linreg_length, data_len),
    Err(LinearRegressionIntensityError::NotEnoughValidData { needed, valid }) =>
        eprintln!("Need {} valid values, found {}", needed, valid),
    Err(e) => eprintln!("Linear Regression Intensity error: {}", e),
}

Python Bindings

Basic Usage

The Python function returns a single NumPy array of intensity values:

import numpy as np
from vector_ta import linear_regression_intensity

data = np.array([101.0, 102.5, 103.0, 104.2, 103.8, 105.1], dtype=np.float64)

values = linear_regression_intensity(
    data,
    lookback_period=12,
    range_tolerance=90.0,
    linreg_length=90,
    kernel="auto",
)

print(values[-5:])
Streaming Real-time Updates

Use the exported stream class for incremental updates:

from vector_ta import LinearRegressionIntensityStream

stream = LinearRegressionIntensityStream(
    lookback_period=12,
    range_tolerance=90.0,
    linreg_length=90,
)

for value in price_feed:
    current = stream.update(value)
    if current is not None:
        print(current)
Batch Processing

The batch binding returns a dict with the matrix plus parameter axes expanded per combo:

import numpy as np
from vector_ta import linear_regression_intensity_batch

data = np.array([...], dtype=np.float64)

result = linear_regression_intensity_batch(
    data,
    lookback_period_range=(8, 12, 2),
    range_tolerance_range=(90.0, 90.0, 0.0),
    linreg_length_range=(30, 60, 30),
    kernel="auto",
)

values = result["values"]
lookbacks = result["lookback_periods"]
tolerances = result["range_tolerances"]
linreg_lengths = result["linreg_lengths"]
rows = result["rows"]
cols = result["cols"]

JavaScript/WASM Bindings

Basic Usage

The high-level WASM binding returns a single numeric array:

import { linear_regression_intensity_js } from 'vectorta-wasm';

const data = new Float64Array([101.0, 102.5, 103.0, 104.2, 103.8, 105.1]);

const values = linear_regression_intensity_js(data, 12, 90.0, 90);
console.log(values);
Memory-Efficient Operations

Use the pointer-based exports to write directly into preallocated memory:

import {
  linear_regression_intensity_alloc,
  linear_regression_intensity_free,
  linear_regression_intensity_into,
  memory,
} from 'vectorta-wasm';

const data = new Float64Array([/* input series */]);
const len = data.length;

const inPtr = linear_regression_intensity_alloc(len);
const outPtr = linear_regression_intensity_alloc(len);

new Float64Array(memory.buffer, inPtr, len).set(data);
linear_regression_intensity_into(inPtr, outPtr, len, 12, 90.0, 90);

const values = new Float64Array(memory.buffer, outPtr, len).slice();

linear_regression_intensity_free(inPtr, len);
linear_regression_intensity_free(outPtr, len);
Batch Processing

The batch binding returns an object with flattened values, shape metadata, and combo metadata:

import { linear_regression_intensity_batch_js } from 'vectorta-wasm';

const data = new Float64Array([/* input series */]);

const result = linear_regression_intensity_batch_js(data, {
  lookback_period_range: [8, 12, 2],
  range_tolerance_range: [90.0, 90.0, 0.0],
  linreg_length_range: [30, 60, 30],
});

type BatchResult = {
  values: number[];
  rows: number;
  cols: number;
  combos: Array<{
    lookback_period?: number;
    range_tolerance?: number;
    linreg_length?: number;
  }>;
};

const { values, rows, cols, combos } = result as BatchResult;
console.log(rows, cols, combos);

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