Standardized PSAR Oscillator

Parameters: start = 0.02 | increment = 0.0005 | maximum = 0.2 | standardization_length = 21 | wma_length = 40 | wma_lag = 3 | pivot_left = 15 | pivot_right = 1 | plot_bullish = true | plot_bearish = true

Overview

Standardized PSAR Oscillator starts from a Parabolic SAR trend model, converts that trend distance into a standardized oscillator, and then applies a weighted moving average signal line. On top of the oscillator pair it computes bullish and bearish reversal markers, regular directional events, and weakening states.

The result is a broad event-driven trend oscillator rather than a single line. You get the oscillator, its signal line, and six event series that can be used for divergence-style or trend-transition analysis on the same panel.

Defaults: `start = 0.02`, `increment = 0.0005`, `maximum = 0.2`, `standardization_length = 21`, `wma_length = 40`, `wma_lag = 3`, `pivot_left = 15`, `pivot_right = 1`, `plot_bullish = true`, and `plot_bearish = true`.

Implementation Examples

Run the oscillator on candles or on explicit HLC slices.

use vector_ta::indicators::standardized_psar_oscillator::{
    standardized_psar_oscillator,
    StandardizedPsarOscillatorInput,
    StandardizedPsarOscillatorParams,
};

let out = standardized_psar_oscillator(&StandardizedPsarOscillatorInput::from_slices(
    &high,
    &low,
    &close,
    StandardizedPsarOscillatorParams::default(),
))?;

println!("{:?}", out.oscillator.last());
println!("{:?}", out.bullish_reversal.last());

API Reference

Input Methods
StandardizedPsarOscillatorInput::from_candles(&Candles, StandardizedPsarOscillatorParams)
    -> StandardizedPsarOscillatorInput

StandardizedPsarOscillatorInput::from_slices(&[f64], &[f64], &[f64], StandardizedPsarOscillatorParams)
    -> StandardizedPsarOscillatorInput

StandardizedPsarOscillatorInput::with_default_candles(&Candles)
    -> StandardizedPsarOscillatorInput
Parameters Structure
pub struct StandardizedPsarOscillatorParams {
    pub start: Option<f64>,
    pub increment: Option<f64>,
    pub maximum: Option<f64>,
    pub standardization_length: Option<usize>,
    pub wma_length: Option<usize>,
    pub wma_lag: Option<usize>,
    pub pivot_left: Option<usize>,
    pub pivot_right: Option<usize>,
    pub plot_bullish: Option<bool>,
    pub plot_bearish: Option<bool>,
}
Output Structure
pub struct StandardizedPsarOscillatorOutput {
    pub oscillator: Vec<f64>,
    pub ma: Vec<f64>,
    pub bullish_reversal: Vec<f64>,
    pub bearish_reversal: Vec<f64>,
    pub regular_bullish: Vec<f64>,
    pub regular_bearish: Vec<f64>,
    pub bullish_weakening: Vec<f64>,
    pub bearish_weakening: Vec<f64>,
}
Validation, Warmup & Events
  • High, low, and close must all be present, non-empty, and equal in length.
  • The PSAR coefficients must remain valid finite values and the lookback-style parameters must fit within the data length.
  • The direct path validates standardization length, weighted moving average length and lag, plus both pivot windows.
  • The stream path returns Option<(f64, f64, f64, f64, f64, f64, f64, f64)> for oscillator, signal line, and the six event series.
  • Batch mode sweeps all numeric axes and preserves the bullish and bearish event toggles for every combo.
Builder, Streaming & Batch APIs
StandardizedPsarOscillatorBuilder::new()
    .start(f64)
    .increment(f64)
    .maximum(f64)
    .standardization_length(usize)
    .wma_length(usize)
    .wma_lag(usize)
    .pivot_left(usize)
    .pivot_right(usize)
    .plot_bullish(bool)
    .plot_bearish(bool)
    .kernel(Kernel)
    .apply(&Candles)
    .apply_slices(&[f64], &[f64], &[f64])
    .into_stream()

StandardizedPsarOscillatorStream::try_new(params)
stream.update(high, low, close)
    -> Option<(f64, f64, f64, f64, f64, f64, f64, f64)>

StandardizedPsarOscillatorBatchBuilder::new()
    .start_range(start, end, step)
    .increment_range(start, end, step)
    .maximum_range(start, end, step)
    .standardization_length_range(start, end, step)
    .wma_length_range(start, end, step)
    .wma_lag_range(start, end, step)
    .pivot_left_range(start, end, step)
    .pivot_right_range(start, end, step)
    .plot_bullish(bool)
    .plot_bearish(bool)
    .kernel(Kernel)
    .apply(&Candles)
    .apply_slices(&[f64], &[f64], &[f64])

Python Bindings

Python exposes one scalar function returning a dictionary of eight arrays, one stream class returning an eight-value tuple, and one batch helper returning reshaped matrices plus the expanded parameter axes.

from vector_ta import (
    standardized_psar_oscillator,
    standardized_psar_oscillator_batch,
    StandardizedPsarOscillatorStream,
)

out = standardized_psar_oscillator(high, low, close)
stream = StandardizedPsarOscillatorStream()
point = stream.update(high[-1], low[-1], close[-1])

batch = standardized_psar_oscillator_batch(
    high,
    low,
    close,
    start_range=(0.02, 0.04, 0.02),
    standardization_length_range=(21, 31, 10),
)

JavaScript/WASM Bindings

The WASM layer exposes scalar and batch helpers plus low-level pointer-based APIs that fill eight separate output buffers.

import init, {
  standardized_psar_oscillator_js,
  standardized_psar_oscillator_batch,
  standardized_psar_oscillator_alloc,
  standardized_psar_oscillator_free,
  standardized_psar_oscillator_into,
  standardized_psar_oscillator_batch_into,
} from "vector-ta-wasm";

await init();

const out = standardized_psar_oscillator_js(high, low, close, 0.02, 0.0005, 0.2, 21, 40, 3, 15, 1, true, true);
const batch = standardized_psar_oscillator_batch(high, low, close, {
  start_range: [0.02, 0.04, 0.02],
  increment_range: [0.0005, 0.0010, 0.0005],
  maximum_range: [0.2, 0.3, 0.1],
  standardization_length_range: [21, 31, 10],
  wma_length_range: [30, 40, 10],
  wma_lag_range: [3, 5, 2],
  pivot_left_range: [15, 21, 6],
  pivot_right_range: [1, 3, 2],
  plot_bullish: true,
  plot_bearish: 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