DecisionPoint Breadth Swenlin Trading Oscillator

Overview

DecisionPoint Breadth Swenlin Trading Oscillator is a market-breadth study built from advancing and declining participation rather than from price. Each valid input pair is transformed into a normalized breadth value using the difference between advancers and decliners divided by their sum, then scaled by 1000. That produces a broad participation oscillator where positive values reflect stronger upside breadth and negative values reflect downside breadth pressure.

VectorTA smooths that raw breadth reading in two stages. It first applies a 4-period EMA to the normalized breadth line, then takes a 5-sample SMA of the EMA output. This gives the oscillator a short reaction time while still reducing the bar-to-bar noise that usually shows up in raw advance-decline data. The result is a fixed-rule breadth oscillator with no user tuning beyond the input data itself.

Defaults: this indicator uses fixed internal settings with `EMA length = 4`, `SMA length = 5`, and `multiplier = 1000.0`.

Implementation Examples

Compute the oscillator directly from advancing and declining breadth counts.

use vector_ta::indicators::decisionpoint_breadth_swenlin_trading_oscillator::{
    decisionpoint_breadth_swenlin_trading_oscillator,
    DecisionPointBreadthSwenlinTradingOscillatorInput,
    DecisionPointBreadthSwenlinTradingOscillatorParams,
};

let output = decisionpoint_breadth_swenlin_trading_oscillator(
    &DecisionPointBreadthSwenlinTradingOscillatorInput::from_slices(
        &advancing,
        &declining,
        DecisionPointBreadthSwenlinTradingOscillatorParams,
    )
)?;

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

API Reference

Input Methods
DecisionPointBreadthSwenlinTradingOscillatorInput::from_slices(
    &[f64],
    &[f64],
    DecisionPointBreadthSwenlinTradingOscillatorParams,
) -> DecisionPointBreadthSwenlinTradingOscillatorInput
Parameters Structure
pub struct DecisionPointBreadthSwenlinTradingOscillatorParams; // no user parameters
Output Structure
pub struct DecisionPointBreadthSwenlinTradingOscillatorOutput {
    pub values: Vec<f64>,
}
Validation, Warmup & NaNs
  • The advancing and declining slices must be non-empty and have identical lengths.
  • A valid breadth pair requires finite inputs and a non-zero advancing plus declining total.
  • The indicator needs at least 5 valid breadth pairs before the SMA stage can return a value.
  • Warmup is fixed at 4 bars, which the streaming API exposes via get_warmup_period().
  • Streaming resets on invalid breadth pairs and returns None until the warmup rebuilds.
  • Batch mode is still validated and will reject non-batch kernels passed to the batch entry point.
Builder, Streaming & Batch APIs
// Builder
DecisionPointBreadthSwenlinTradingOscillatorBuilder::new()
    .kernel(Kernel)
    .apply_slices(&[f64], &[f64])

DecisionPointBreadthSwenlinTradingOscillatorBuilder::new()
    .into_stream()

// Stream
DecisionPointBreadthSwenlinTradingOscillatorStream::try_new(
    DecisionPointBreadthSwenlinTradingOscillatorParams
)
DecisionPointBreadthSwenlinTradingOscillatorStream::update(f64, f64) -> Option<f64>
DecisionPointBreadthSwenlinTradingOscillatorStream::reset()
DecisionPointBreadthSwenlinTradingOscillatorStream::get_warmup_period() -> usize

// Batch
DecisionPointBreadthSwenlinTradingOscillatorBatchBuilder::new()
    .kernel(Kernel)
    .apply_slices(&[f64], &[f64])
Error Handling
pub enum DecisionPointBreadthSwenlinTradingOscillatorError {
    EmptyInputData,
    AllValuesNaN,
    InconsistentSliceLengths { advancing_len: usize, declining_len: usize },
    NotEnoughValidData { needed: usize, valid: usize },
    OutputLengthMismatch { expected: usize, got: usize },
    InvalidKernelForBatch(Kernel),
}

Python Bindings

Python exposes an array-returning single-run function, a streaming class, and a batch function. The single-run binding returns one NumPy array of oscillator values. Batch returns a one-row values matrix plus the final rows and cols shape, since there is no parameter sweep for this indicator.

import numpy as np
from vector_ta import (
    decisionpoint_breadth_swenlin_trading_oscillator,
    decisionpoint_breadth_swenlin_trading_oscillator_batch,
    DecisionPointBreadthSwenlinTradingOscillatorStream,
)

advancing = np.asarray(advancing_values, dtype=np.float64)
declining = np.asarray(declining_values, dtype=np.float64)

values = decisionpoint_breadth_swenlin_trading_oscillator(
    advancing,
    declining,
    kernel="auto",
)

stream = DecisionPointBreadthSwenlinTradingOscillatorStream()
print(stream.warmup_period)
print(stream.update(advancing[-1], declining[-1]))

batch = decisionpoint_breadth_swenlin_trading_oscillator_batch(
    advancing,
    declining,
    kernel="auto",
)

print(batch["rows"], batch["cols"], batch["values"])

JavaScript/WASM Bindings

The WASM layer exposes a direct array-returning single-run wrapper, an object-returning batch wrapper, and lower-level allocation and in-place exports. The batch wrapper still returns a one-row matrix shape and an empty config surface because the indicator has no user-tunable parameters.

import init, {
  decisionpoint_breadth_swenlin_trading_oscillator_js,
  decisionpoint_breadth_swenlin_trading_oscillator_batch_js,
} from "/pkg/vector_ta.js";

await init();

const advancing = new Float64Array(advancingValues);
const declining = new Float64Array(decliningValues);

const values = decisionpoint_breadth_swenlin_trading_oscillator_js(
  advancing,
  declining,
);
console.log(values);

const batch = decisionpoint_breadth_swenlin_trading_oscillator_batch_js(
  advancing,
  declining,
  {},
);

console.log(batch.values, batch.rows, batch.cols);

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