Rolling Deviation

Parameters: period = 9 | devtype = 0 (0–3)

Overview

Rolling Deviation measures price dispersion over a moving window using multiple statistical methods that offer different perspectives on volatility. The indicator provides four deviation types to choose from based on your analysis needs. Standard Deviation calculates the classic statistical measure of variance from the mean, capturing both normal fluctuations and extreme moves. Mean Absolute Deviation (MAD) averages the absolute distances from the mean, providing a more stable measure less influenced by outliers. Median Absolute Deviation (MedAD) uses the median as its center point, offering maximum robustness against extreme values. The fourth option provides an alternative standard deviation calculation for specific use cases.

Each deviation type reveals different aspects of market behavior and volatility patterns. Standard Deviation remains the most sensitive to price spikes and crashes, making it ideal for detecting volatility expansions quickly. MAD provides a middle ground, smoothing out extreme moves while still responding to genuine volatility changes. MedAD proves most stable during erratic markets, filtering out outliers that might distort other measures. The choice between methods depends on whether you prioritize sensitivity to all price movements or stability against anomalous spikes.

Traders use Rolling Deviation to assess market risk, set position sizes, and identify volatility regimes. Rising deviation values warn of increasing uncertainty, prompting defensive adjustments like wider stops or smaller positions. Falling deviation indicates consolidation, potentially signaling breakout setups or opportunities for selling options premium. The indicator serves as a key component in adaptive trading systems that adjust parameters based on current volatility. Many traders combine different deviation types, using sensitive measures for short term signals and robust measures for longer term risk assessment.

Defaults: period=9, devtype=0 (StdDev).

Implementation Examples

Compute rolling deviation in a few lines:

use vectorta::indicators::deviation::{deviation, DeviationInput, DeviationParams};
use vectorta::utilities::data_loader::{Candles, read_candles_from_csv};

// From a price slice (defaults: period=9, devtype=0=StdDev)
let prices = vec![100.0, 102.0, 101.5, 103.0, 105.0, 104.5];
let input = DeviationInput::with_defaults(&prices);
let result = deviation(&input)?;

// Custom parameters (e.g., Median Absolute Deviation)
let params = DeviationParams { period: Some(20), devtype: Some(2) };
let input = DeviationInput::from_slice(&prices, params);
let result = deviation(&input)?;

// From Candles with default params (source = "close")
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let input = DeviationInput::with_default_candles(&candles);
let result = deviation(&input)?;

// Access the values
for v in result.values { println!("dev: {}", v); }

API Reference

Input Methods
// From price slice
DeviationInput::from_slice(&[f64], DeviationParams) -> DeviationInput

// From candles with custom source
DeviationInput::from_candles(&Candles, &str, DeviationParams) -> DeviationInput

// With defaults (period=9, devtype=0) from slice
DeviationInput::with_defaults(&[f64]) -> DeviationInput

// With defaults from candles (source = "close")
DeviationInput::with_default_candles(&Candles) -> DeviationInput
Parameters Structure
pub struct DeviationParams {
    pub period: Option<usize>,  // Default: 9 (must be > 0)
    pub devtype: Option<usize>, // Default: 0 (0=StdDev, 1=MAD, 2=MedAD, 3=StdDev-like)
}
Output Structure
pub struct DeviationOutput {
    pub values: Vec<f64>, // Rolling deviation values
}
Validation, Warmup & NaNs
  • period > 0 and period ≤ len; devtype ∈ {0,1,2,3}.
  • Errors: DeviationError::AllValuesNaN, DeviationError::InvalidPeriod { period, data_len }, DeviationError::NotEnoughValidData { needed, valid }, DeviationError::InvalidDevType { devtype }, DeviationError::CalculationError(..).
  • Warmup: indices [0 .. first_valid + period − 2] are NaN (prefix seeded via alloc_with_nan_prefix).
  • Any non‑finite in the current window yields NaN at that index; streaming returns None until the window fills.
Error Handling
use vectorta::indicators::deviation::{deviation, DeviationError};

match deviation(&input) {
    Ok(output) => process(output.values),
    Err(DeviationError::AllValuesNaN) => eprintln!("All input values are NaN"),
    Err(DeviationError::InvalidPeriod &#123; period, data_len &#125;) =>
        eprintln!("Invalid period {} for data length {}", period, data_len),
    Err(DeviationError::NotEnoughValidData &#123; needed, valid &#125;) =>
        eprintln!("Need {} valid values after first finite; got {}", needed, valid),
    Err(DeviationError::InvalidDevType &#123; devtype &#125;) =>
        eprintln!("devtype must be 0..=3, got {}", devtype),
    Err(e) => eprintln!("deviation error: {}", e),
}

Python Bindings

Basic Usage

Calculate deviation using NumPy arrays (defaults: period=9, devtype=0):

import numpy as np
from vectorta import deviation

prices = np.array([100.0, 102.0, 101.5, 103.0, 105.0, 104.5])

# Default (StdDev)
out = deviation(prices, period=9, devtype=0)

# Median Absolute Deviation
out = deviation(prices, period=20, devtype=2, kernel="auto")

print(out)
Streaming Real-time Updates

Incremental updates with DeviationStream:

from vectorta import DeviationStream

stream = DeviationStream(period=9, devtype=0)
for price in price_feed:
    value = stream.update(price)
    if value is not None:
        print("dev:", value)
Batch Parameter Optimization

Sweep period and devtype:

import numpy as np
from vectorta import deviation_batch

prices = np.array([...], dtype=float)

res = deviation_batch(
    prices,
    period_range=(5, 30, 5),
    devtype_range=(0, 2, 1),
    kernel="auto"
)

print(res["values"].shape)  # (num_combos, len(prices))
print(res["periods"])       # tested periods
print(res["devtypes"])      # tested devtypes
CUDA Acceleration

CUDA support for Deviation is coming soon. The API will mirror other CUDA-enabled indicators.

JavaScript/WASM Bindings

Basic Usage

Calculate Deviation in JavaScript/TypeScript:

import { deviation_js } from 'vectorta-wasm';

const prices = new Float64Array([100, 102, 101.5, 103, 105, 104.5]);

// period=9, devtype=0 (StdDev)
const values = deviation_js(prices, 9, 0);
console.log('Deviation:', values);
Memory‑Efficient Operations

Use zero‑copy helpers for large arrays:

import { deviation_alloc, deviation_free, deviation_into, memory } from 'vectorta-wasm';

const prices = new Float64Array([/* your data */]);
const n = prices.length;

// Allocate WASM memory
const inPtr = deviation_alloc(n);
const outPtr = deviation_alloc(n);

// Copy input into WASM memory
new Float64Array(memory.buffer, inPtr, n).set(prices);

// Compute directly into output buffer: (in_ptr, len, period, devtype, out_ptr)
deviation_into(inPtr, n, 9, 0, outPtr);

// Read results
const out = new Float64Array(memory.buffer, outPtr, n).slice();

// Free WASM buffers
deviation_free(inPtr, n);
deviation_free(outPtr, n);
Batch Processing

Sweep parameters efficiently with metadata helpers:

import { deviation_batch as deviationBatch, deviation_batch_metadata as deviationBatchMetadata } from 'vectorta-wasm';

const prices = new Float64Array([/* historical prices */]);

// Metadata about combinations (period, devtype pairs)
const meta = deviationBatchMetadata(5, 15, 5, 0, 2, 1);
const combos = meta.length / 2;

// Unified batch call with config object
const cfg = { period_range: [5, 15, 5], devtype_range: [0, 2, 1] };
const batch = deviationBatch(prices, cfg);
// batch = { values: Float64Array, combos: number, rows: number, cols: number }

Performance Analysis

Comparison:
View:
Loading chart...

AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU) | Benchmarks: 2026-01-05

Related Indicators