Rolling Z-Score Trend
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_periodmust 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
Across sizes, Rust CPU runs about 1.14× faster than Tulip C in this benchmark.
AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU)