Linear Correlation Oscillator

Parameters: source = close | period = 14

Overview

Linear Correlation Oscillator measures how strongly the recent price window aligns with a straight time sequence. For each completed window, the implementation computes the correlation between x = 1..period and the selected price values, clamps the result to [-1, 1], and returns that correlation as the oscillator value. Readings near 1.0 indicate a strong positive linear relationship, readings near -1.0 indicate a strong negative linear relationship, and values around 0.0 indicate weak linear structure.

Defaults: candle source = "close" and period = 14. Candle helpers and the builder apply(&Candles) path both use close.

Implementation Examples

Use candle helpers or a plain slice input:

use vector_ta::indicators::linear_correlation_oscillator::{
    linear_correlation_oscillator,
    LinearCorrelationOscillatorInput,
    LinearCorrelationOscillatorParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};

let data = vec![100.0, 100.4, 100.9, 101.5, 102.0, 102.6, 103.1, 103.5];
let input = LinearCorrelationOscillatorInput::from_slice(
    &data,
    LinearCorrelationOscillatorParams { period: Some(14) },
);
let out = linear_correlation_oscillator(&input)?;

// Candles path defaults to close
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let candle_input = LinearCorrelationOscillatorInput::with_default_candles(&candles);
let candle_out = linear_correlation_oscillator(&candle_input)?;

println!("{:?}", out.values.last());

API Reference

Input Methods
// From candles with explicit source
LinearCorrelationOscillatorInput::from_candles(
    &Candles,
    &str,
    LinearCorrelationOscillatorParams,
) -> LinearCorrelationOscillatorInput

// From a plain slice
LinearCorrelationOscillatorInput::from_slice(
    &[f64],
    LinearCorrelationOscillatorParams,
) -> LinearCorrelationOscillatorInput

// Default candles source is close
LinearCorrelationOscillatorInput::with_default_candles(&Candles)
    -> LinearCorrelationOscillatorInput
Parameters and Output
pub struct LinearCorrelationOscillatorParams {
    pub period: Option<usize>, // default 14
}

pub struct LinearCorrelationOscillatorOutput {
    pub values: Vec<f64>,
}
Builder, Stream, and Batch Surface
LinearCorrelationOscillatorBuilder::new()
    .period(usize)
    .kernel(Kernel)
    .apply(&Candles) -> Result<LinearCorrelationOscillatorOutput, _>

LinearCorrelationOscillatorBuilder::new()
    .apply_slice(&[f64]) -> Result<LinearCorrelationOscillatorOutput, _>

LinearCorrelationOscillatorBuilder::new()
    .into_stream() -> Result<LinearCorrelationOscillatorStream, _>

LinearCorrelationOscillatorStream::update(value: f64) -> Option<f64>

LinearCorrelationOscillatorBatchBuilder::new()
    .kernel(Kernel)
    .period_range(start, end, step)
    .period_static(period)
    .apply_slice(&[f64]) -> Result<LinearCorrelationOscillatorBatchOutput, _>

LinearCorrelationOscillatorBatchBuilder::new()
    .apply_candles(&Candles, source: &str) -> Result<LinearCorrelationOscillatorBatchOutput, _>
Validation, Warmup, and NaNs
  • Inputs must be non-empty. If every value is NaN, the indicator returns AllValuesNaN.
  • period must satisfy 1 <= period <= data.len().
  • The first valid bar is the first value that is not NaN.
  • The scalar validator requires valid > period + 1, so at least period + 2 valid points from the first valid bar.
  • The scalar output allocates a NaN prefix of first_valid + period + 1.
  • If the data after the first valid bar contains any NaN, the implementation falls back to a slower window-by-window path and writes NaN for any affected window.
  • The stream buffers period + 2 points and returns None until that buffer is full. It also returns None if the active window contains NaN.
Computation and Batch Output
  • The correlation uses a fixed time axis x = 1..period and rolling sums of y, y^2, and weighted x * y.
  • Variance in y is stabilized by snapping tiny negative floating-point drift up to 0.0 when it is between -1e-12 and 0.0.
  • Non-finite or zero denominators return NaN; otherwise the correlation is clamped to [-1.0, 1.0].
  • Batch range default is period = (14, 258, 1).
  • Rust batch output is LinearCorrelationOscillatorBatchOutput with flattened row-major values, plus combos, rows, and cols.
  • Helper methods row_for_params() and values_for() let you recover one row by period.
Error Handling
use vector_ta::indicators::linear_correlation_oscillator::LinearCorrelationOscillatorError;

// Common errors:
// - EmptyInputData
// - AllValuesNaN
// - InvalidPeriod
// - NotEnoughValidData
// - OutputLengthMismatch
// - InvalidRange
// - InvalidKernelForBatch

Python Bindings

Basic Usage

The Python scalar function returns one NumPy array:

import numpy as np
from vector_ta import linear_correlation_oscillator

values = linear_correlation_oscillator(
    np.asarray(data, dtype=np.float64),
    period=14,
    kernel="auto",
)
Streaming Real-time Updates

The Python stream class returns None until enough values have accumulated:

from vector_ta import LinearCorrelationOscillatorStream

stream = LinearCorrelationOscillatorStream(period=14)

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

Python batch returns values and periods keys:

from vector_ta import linear_correlation_oscillator_batch

result = linear_correlation_oscillator_batch(
    np.asarray(data, dtype=np.float64),
    period_range=(14, 30, 4),
    kernel="auto",
)

values = result["values"]
periods = result["periods"]

JavaScript/WASM Bindings

Basic Usage

The scalar WASM export returns a single Float64Array:

import { linear_correlation_oscillator_js } from 'vectorta-wasm';

const values = linear_correlation_oscillator_js(new Float64Array(data), 14);
console.log(values);
Host Buffer API

The low-level WASM path writes one output array of length len:

import {
  linear_correlation_oscillator_alloc,
  linear_correlation_oscillator_free,
  linear_correlation_oscillator_into,
} from 'vectorta-wasm';

const len = data.length;
const outPtr = linear_correlation_oscillator_alloc(len);

try {
  linear_correlation_oscillator_into(inPtr, outPtr, len, 14);
} finally {
  linear_correlation_oscillator_free(outPtr, len);
}
Batch Processing

The current WASM batch export name is linear_correlation_oscillator_batch and it returns an object with values, combos, rows, and cols:

import { linear_correlation_oscillator_batch } from 'vectorta-wasm';

const batch = linear_correlation_oscillator_batch(new Float64Array(data), {
  period_range: [14, 30, 4],
}) as {
  values: number[];
  combos: Array<{ period?: number }>;
  rows: number;
  cols: number;
};

console.log(batch.rows, batch.cols);
console.log(batch.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