EWMA Volatility
lambda = 0.94 (0–1) Overview
EWMA Volatility measures how fast returns are varying by first converting the input price series into squared log returns, then smoothing those squared returns with an exponentially weighted moving average. The final output is the square root of that smoothed variance estimate, scaled by `100`, so the resulting series reads as a percentage-style volatility line rather than a raw variance measure.
The single parameter is the decay factor `lambda`. Higher values make the estimate retain more memory and react more slowly to fresh volatility shocks, while lower values make the line respond faster to recent return changes. Candle mode defaults to `close`, and the streaming API seeds itself from valid log returns before it starts emitting finite values.
Defaults: EWMA Volatility uses `lambda = 0.94` and defaults candle input to `close`.
Implementation Examples
Compute EWMA volatility from a close series or from candle closes.
use vector_ta::indicators::ewma_volatility::{
ewma_volatility,
EwmaVolatilityInput,
EwmaVolatilityParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
let close = vec![100.0, 100.8, 101.4, 100.9, 102.1, 101.7, 103.0];
let output = ewma_volatility(&EwmaVolatilityInput::from_slice(
&close,
EwmaVolatilityParams { lambda: Some(0.94) },
))?;
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let candle_output = ewma_volatility(&EwmaVolatilityInput::with_default_candles(&candles))?;
println!("latest vol = {:?}", output.values.last());
println!("series length = {}", candle_output.values.len()); API Reference
Input Methods ▼
// From candles and a named source field
EwmaVolatilityInput::from_candles(&Candles, &str, EwmaVolatilityParams)
-> EwmaVolatilityInput
// From a raw slice
EwmaVolatilityInput::from_slice(&[f64], EwmaVolatilityParams)
-> EwmaVolatilityInput
// From candles with default parameters
EwmaVolatilityInput::with_default_candles(&Candles)
-> EwmaVolatilityInput Parameters Structure ▼
pub struct EwmaVolatilityParams {
pub lambda: Option<f64>, // default 0.94
} Output Structure ▼
pub struct EwmaVolatilityOutput {
pub values: Vec<f64>,
} Validation, Warmup & NaNs ▼
- The input slice must be non-empty and contain at least one non-NaN value.
lambdamust be finite and in the half-open interval[0, 1).- The effective warmup period is derived from lambda as
round(2 / (1 - lambda) - 1), with a minimum of1. - Only finite positive prices contribute valid log returns.
- Streaming returns
Noneuntil enough valid returns have been collected to seed the EWMA state. - Batch mode validates floating-point ranges and rejects unsupported kernels through
InvalidKernelForBatch.
Builder, Streaming & Batch APIs ▼
// Builder
EwmaVolatilityBuilder::new()
.lambda(f64)
.kernel(Kernel)
.apply_slice(&[f64])
EwmaVolatilityBuilder::new()
.apply(&Candles)
EwmaVolatilityBuilder::new()
.into_stream()
// Stream
EwmaVolatilityStream::try_new(EwmaVolatilityParams)
EwmaVolatilityStream::update(f64) -> Option<f64>
EwmaVolatilityStream::get_warmup_period() -> usize
// Batch
EwmaVolatilityBatchBuilder::new()
.lambda_range(start, end, step)
.lambda_static(f64)
.kernel(Kernel)
.apply_slice(&[f64])
EwmaVolatilityBatchBuilder::new()
.apply_candles(&Candles) Error Handling ▼
pub enum EwmaVolatilityError {
EmptyInputData,
AllValuesNaN,
InvalidLambda { lambda: f64 },
NotEnoughValidData { needed: usize, valid: usize },
OutputLengthMismatch { expected: usize, got: usize },
InvalidRange { start: String, end: String, step: String },
InvalidKernelForBatch(Kernel),
} Python Bindings
Python exposes an array-returning single-run function, a streaming class, and a batch function. The scalar binding returns one NumPy volatility array, while batch returns the values matrix plus the lambda grid used for each row.
import numpy as np
from vector_ta import ewma_volatility, ewma_volatility_batch, EwmaVolatilityStream
data = np.asarray(close_values, dtype=np.float64)
values = ewma_volatility(data, lambda_=0.94, kernel="auto")
stream = EwmaVolatilityStream(lambda_=0.94)
print(stream.get_warmup_period())
print(stream.update(data[-1]))
batch = ewma_volatility_batch(
data,
lambda_range=(0.90, 0.98, 0.02),
kernel="auto",
)
print(batch["values"].shape)
print(batch["lambdas"], batch["rows"], batch["cols"]) JavaScript/WASM Bindings
The WASM layer exposes a direct array-returning scalar wrapper, an object-returning batch wrapper, and lower-level allocation and in-place exports. The standard JavaScript path returns one volatility array, while batch returns flattened values, parameter combos, and the rows and cols shape.
import init, { ewma_volatility_js, ewma_volatility_batch_js } from "/pkg/vector_ta.js";
await init();
const data = new Float64Array(closeValues);
const values = ewma_volatility_js(data, 0.94);
console.log(values);
const batch = ewma_volatility_batch_js(data, {
lambda_range: [0.90, 0.98, 0.02],
});
console.log(batch.values, batch.combos, 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)