Volume Zone Oscillator

Parameters: length = 14 | intraday_smoothing = true | noise_filter = 4

Overview

Volume Zone Oscillator is a single-line volume-pressure oscillator built from close and volume data, with optional intraday smoothing and a small noise filter. It is useful when you want one compact view of whether volume is accumulating on advancing or declining price action.

In VectorTA the indicator works on close-plus-volume slices or candle data, supports streaming updates, and exposes a batch sweep over the main lookback and noise-filter controls. That makes it a practical volume-confirmation study for trend systems and short-term momentum filters.

Defaults: `length = 14`, `intraday_smoothing = true`, and `noise_filter = 4`.

Implementation Examples

Run the oscillator on direct close-plus-volume slices or on candle data with the default settings.

use vector_ta::indicators::volume_zone_oscillator::{
    volume_zone_oscillator,
    VolumeZoneOscillatorInput,
    VolumeZoneOscillatorParams,
};

let output = volume_zone_oscillator(&VolumeZoneOscillatorInput::from_slices(
    &close,
    &volume,
    VolumeZoneOscillatorParams::default(),
))?;

println!("vzo = {:?}", output.values.last());

API Reference

Input Methods
VolumeZoneOscillatorInput::from_candles(&Candles, VolumeZoneOscillatorParams)
    -> VolumeZoneOscillatorInput

VolumeZoneOscillatorInput::from_slices(&[f64], &[f64], VolumeZoneOscillatorParams)
    -> VolumeZoneOscillatorInput

VolumeZoneOscillatorInput::with_default_candles(&Candles)
    -> VolumeZoneOscillatorInput
Parameters Structure
pub struct VolumeZoneOscillatorParams {
    pub length: Option<usize>,
    pub intraday_smoothing: Option<bool>,
    pub noise_filter: Option<usize>,
}
Output Structure
pub struct VolumeZoneOscillatorOutput {
    pub values: Vec<f64>,
}
Validation, Warmup & NaNs
  • Close and volume inputs must share the same non-zero length and contain enough valid data for the resolved length.
  • The resolved noise_filter must also pass the Rust validation checks.
  • Streaming updates return the current oscillator value directly once the state is available.
  • Batch mode validates the length and noise-filter ranges before building the matrix.
Builder, Streaming & Batch APIs
VolumeZoneOscillatorBuilder::new()
    .length(usize)
    .intraday_smoothing(bool)
    .noise_filter(usize)
    .kernel(Kernel)
    .apply(&Candles)
    .apply_slices(&[f64], &[f64])
    .into_stream()

VolumeZoneOscillatorStream::try_new(params)
stream.update(close, volume) -> f64

VolumeZoneOscillatorBatchBuilder::new()
    .length_range(start, end, step)
    .noise_filter_range(start, end, step)
    .intraday_smoothing(bool)
    .apply_slice(&[f64], &[f64])

Python Bindings

Python exposes direct, stream, and batch helpers for the single VZO line.

from vector_ta import volume_zone_oscillator, volume_zone_oscillator_batch, VolumeZoneOscillatorStream

single = volume_zone_oscillator(close, volume)
stream = VolumeZoneOscillatorStream()
point = stream.update(close[-1], volume[-1])
batch = volume_zone_oscillator_batch(
    close,
    volume,
    length_range=(10, 30, 5),
    noise_filter_range=(2, 6, 2),
    intraday_smoothing=True,
)

JavaScript/WASM Bindings

The WASM layer exposes direct, batch, allocation, and into-buffer helpers for VZO calculations.

import init, { volume_zone_oscillator_js, volume_zone_oscillator_batch_js } from "vector-ta-wasm";

await init();

const single = volume_zone_oscillator_js(close, volume, 14, true, 4);
const batch = volume_zone_oscillator_batch_js(close, volume, {
  length_range: [10, 30, 5],
  noise_filter_range: [2, 6, 2],
  intraday_smoothing: true,
});

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