Rolling Z-Score Trend

Parameters: lookback_period = 20

Overview

Rolling Z-Score Trend measures how far the latest value sits from its rolling mean in standard-deviation units. That produces a normalized trend or stretch reading that is comparable across different symbols and price scales.

VectorTA then smooths the raw z-score recursively and derives a momentum series from the change in that smoothed value. The pair gives you both the standardized level and the current rate of change of that level.

Defaults: `lookback_period = 20`.

Implementation Examples

Run the indicator on candle data or a direct slice and inspect the smoothed z-score plus its momentum.

use vector_ta::indicators::rolling_z_score_trend::{
    rolling_z_score_trend,
    RollingZScoreTrendInput,
    RollingZScoreTrendParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};

let output = rolling_z_score_trend(&RollingZScoreTrendInput::from_slice(
    &close,
    RollingZScoreTrendParams {
        lookback_period: Some(20),
    },
))?;

let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let candle_output =
    rolling_z_score_trend(&RollingZScoreTrendInput::with_default_candles(&candles))?;

println!("zscore = {:?}", output.zscore.last());
println!("momentum = {:?}", candle_output.momentum.last());

API Reference

Input Methods
RollingZScoreTrendInput::from_candles(&Candles, &str, RollingZScoreTrendParams)
    -> RollingZScoreTrendInput

RollingZScoreTrendInput::from_slice(&[f64], RollingZScoreTrendParams)
    -> RollingZScoreTrendInput

RollingZScoreTrendInput::with_default_candles(&Candles)
    -> RollingZScoreTrendInput
Parameters Structure
pub struct RollingZScoreTrendParams {
    pub lookback_period: Option<usize>,
}
Output Structure
pub struct RollingZScoreTrendOutput {
    pub zscore: Vec<f64>,
    pub momentum: Vec<f64>,
}
Validation, Warmup & NaNs
  • The input series must be non-empty and contain a sufficiently long run of finite values.
  • lookback_period must be greater than zero and cannot exceed the available data length.
  • The z-score output becomes finite once the lookback window is full, and momentum becomes finite one update later.
  • Streaming resets when it encounters a non-finite input value.
  • Batch mode validates the lookback sweep axis and rejects unsupported kernels through InvalidKernelForBatch.
Builder, Streaming & Batch APIs
RollingZScoreTrendBuilder::new()
    .lookback_period(usize)
    .kernel(Kernel)
    .apply(&Candles)
    .apply_candles(&Candles, &str)
    .apply_slice(&[f64])
    .into_stream()

RollingZScoreTrendStream::try_new(params)
stream.update(f64) -> Option<(f64, f64)>
stream.reset()
stream.get_warmup_period() -> usize

RollingZScoreTrendBatchBuilder::new()
    .lookback_period_range((usize, usize, usize))
    .kernel(Kernel)
    .apply_slice(&[f64])
    .apply_candles(&Candles, &str)
Error Handling
pub enum RollingZScoreTrendError {
    EmptyInputData,
    AllValuesNaN,
    InvalidLookbackPeriod { lookback_period: usize, data_len: usize },
    NotEnoughValidData { needed: usize, valid: usize },
    OutputLengthMismatch { expected: usize, got: usize },
    InvalidRange { start: usize, end: usize, step: usize },
    InvalidKernelForBatch(Kernel),
    MismatchedOutputLen { dst_len: usize, expected_len: usize },
    InvalidInput { msg: String },
}

Python Bindings

Python exposes a scalar function, a streaming class, and a batch helper. The scalar call returns z-score and momentum arrays, the stream emits a two-value tuple or None, and the batch helper returns reshaped matrices together with the tested lookback windows.

from vector_ta import (
    rolling_z_score_trend,
    rolling_z_score_trend_batch,
    RollingZScoreTrendStream,
)

zscore, momentum = rolling_z_score_trend(
    close,
    lookback_period=20,
    kernel="auto",
)

stream = RollingZScoreTrendStream(lookback_period=20)
print(stream.update(close[-1]))

batch = rolling_z_score_trend_batch(
    close,
    lookback_period_range=(10, 30, 10),
    kernel="auto",
)

print(batch["rows"], batch["cols"])

JavaScript/WASM Bindings

The WASM layer exposes scalar, batch, allocation, and into-buffer helpers. The high-level calls return plain JS objects containing the z-score and momentum arrays, while the low-level APIs write those arrays into caller-managed memory.

import init, {
  rolling_z_score_trend_js,
  rolling_z_score_trend_batch_js,
  rolling_z_score_trend_alloc,
  rolling_z_score_trend_free,
  rolling_z_score_trend_into,
  rolling_z_score_trend_batch_into,
} from "vector-ta-wasm";

await init();

const out = rolling_z_score_trend_js(close, 20);
console.log(out.zscore, out.momentum);

const batch = rolling_z_score_trend_batch_js(close, {
  lookback_period_range: [10, 30, 10],
});

console.log(batch.rows, batch.cols);

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