Relative Strength Index Wave Indicator

Parameters: rsi_length = 14 | length1 = 2 | length2 = 5 | length3 = 9 | length4 = 13

Overview

Relative Strength Index Wave Indicator turns RSI behavior into a multi-line wave display. It computes RSI-style values for the selected source, the high series, and the low series, combines them into a composite momentum reading, and then smooths that reading with four weighted moving averages of increasing length.

The resulting wave stack gives a fast-to-slow view of RSI structure instead of a single oscillator line. A separate state output compares the shortest wave against the next one to label positive acceleration, positive deceleration, negative acceleration, and negative deceleration.

Defaults: `source = "hlcc4"`, `rsi_length = 14`, `length1 = 2`, `length2 = 5`, `length3 = 9`, and `length4 = 13`.

Implementation Examples

Run the indicator on candles with the default `hlcc4` source or supply source/high/low slices directly.

use vector_ta::indicators::relative_strength_index_wave_indicator::{
    relative_strength_index_wave_indicator,
    RelativeStrengthIndexWaveIndicatorInput,
    RelativeStrengthIndexWaveIndicatorParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};

let source = vec![100.1, 100.6, 101.0, 100.8, 101.5, 102.0];
let high = vec![100.8, 101.1, 101.5, 101.2, 102.0, 102.4];
let low = vec![99.7, 100.0, 100.5, 100.2, 100.9, 101.3];

let output = relative_strength_index_wave_indicator(
    &RelativeStrengthIndexWaveIndicatorInput::from_slices(
        &source,
        &high,
        &low,
        RelativeStrengthIndexWaveIndicatorParams {
            rsi_length: Some(14),
            length1: Some(2),
            length2: Some(5),
            length3: Some(9),
            length4: Some(13),
        },
    ),
)?;

let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let candle_output = relative_strength_index_wave_indicator(
    &RelativeStrengthIndexWaveIndicatorInput::with_default_candles(&candles),
)?;

println!("wave 1 = {:?}", output.rsi_ma1.last());
println!("state = {:?}", candle_output.state.last());

API Reference

Input Methods
RelativeStrengthIndexWaveIndicatorInput::from_candles(
    &Candles,
    &str,
    RelativeStrengthIndexWaveIndicatorParams,
) -> RelativeStrengthIndexWaveIndicatorInput

RelativeStrengthIndexWaveIndicatorInput::from_slices(
    &[f64],
    &[f64],
    &[f64],
    RelativeStrengthIndexWaveIndicatorParams,
) -> RelativeStrengthIndexWaveIndicatorInput

RelativeStrengthIndexWaveIndicatorInput::with_default_candles(&Candles)
    -> RelativeStrengthIndexWaveIndicatorInput
Parameters Structure
pub struct RelativeStrengthIndexWaveIndicatorParams {
    pub rsi_length: Option<usize>,
    pub length1: Option<usize>,
    pub length2: Option<usize>,
    pub length3: Option<usize>,
    pub length4: Option<usize>,
}
Output Structure
pub struct RelativeStrengthIndexWaveIndicatorOutput {
    pub rsi_ma1: Vec<f64>,
    pub rsi_ma2: Vec<f64>,
    pub rsi_ma3: Vec<f64>,
    pub rsi_ma4: Vec<f64>,
    pub state: Vec<f64>,
}
Validation, Warmup & NaNs
  • The source, high, and low slices must all be non-empty, have identical lengths, and contain at least one finite triplet.
  • rsi_length, length1, length2, length3, and length4 must all be greater than 0.
  • Any non-finite input triplet resets the streaming core and yields NaN output for that update.
  • The wave lines warm up in stages: the RSI stage must initialize first, then each weighted moving average must fill its own window before its line becomes finite.
  • Batch mode validates all sweep axes and rejects unsupported kernels through InvalidKernelForBatch.
Builder, Streaming & Batch APIs
RelativeStrengthIndexWaveIndicatorBuilder::new()
    .source(&'static str)
    .rsi_length(usize)
    .length1(usize)
    .length2(usize)
    .length3(usize)
    .length4(usize)
    .kernel(Kernel)
    .apply(&Candles)
    .apply_slices(&[f64], &[f64], &[f64])
    .into_stream()

RelativeStrengthIndexWaveIndicatorStream::try_new(params)
stream.update(f64, f64, f64) -> (f64, f64, f64, f64, f64)

RelativeStrengthIndexWaveIndicatorBatchBuilder::new()
    .source(&'static str)
    .rsi_length_range((usize, usize, usize))
    .length1_range((usize, usize, usize))
    .length2_range((usize, usize, usize))
    .length3_range((usize, usize, usize))
    .length4_range((usize, usize, usize))
    .kernel(Kernel)
    .apply(&Candles)
    .apply_slices(&[f64], &[f64], &[f64])
Error Handling
pub enum RelativeStrengthIndexWaveIndicatorError {
    EmptyInputData,
    LengthMismatch { source_len: usize, high_len: usize, low_len: usize },
    AllValuesNaN,
    InvalidRsiLength { rsi_length: usize },
    InvalidLength1 { length1: usize },
    InvalidLength2 { length2: usize },
    InvalidLength3 { length3: usize },
    InvalidLength4 { length4: usize },
    OutputLengthMismatch { expected: usize, got: usize },
    InvalidRange { start: String, end: String, step: String },
    InvalidKernelForBatch(Kernel),
}

Python Bindings

Python exposes a scalar function, a streaming class, and a batch helper. The scalar call returns five NumPy arrays, the stream emits a five-value tuple, and the batch helper returns reshaped matrices together with the tested wave-length axes.

from vector_ta import (
    relative_strength_index_wave_indicator,
    relative_strength_index_wave_indicator_batch,
    RelativeStrengthIndexWaveIndicatorStream,
)

rsi_ma1, rsi_ma2, rsi_ma3, rsi_ma4, state = relative_strength_index_wave_indicator(
    source,
    high,
    low,
    rsi_length=14,
    length1=2,
    length2=5,
    length3=9,
    length4=13,
    kernel="auto",
)

stream = RelativeStrengthIndexWaveIndicatorStream(
    rsi_length=14,
    length1=2,
    length2=5,
    length3=9,
    length4=13,
)
print(stream.update(source[-1], high[-1], low[-1]))

batch = relative_strength_index_wave_indicator_batch(
    source,
    high,
    low,
    rsi_length_range=(10, 14, 2),
    length1_range=(2, 4, 2),
    length2_range=(5, 9, 2),
    length3_range=(9, 13, 2),
    length4_range=(13, 17, 2),
    kernel="auto",
)

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

JavaScript/WASM Bindings

The WASM surface exposes scalar, batch, allocation, and into-buffer helpers. The high-level calls return plain JS objects containing the four wave arrays and state array, while the low-level APIs write those arrays into caller-managed memory.

import init, {
  relative_strength_index_wave_indicator_js,
  relative_strength_index_wave_indicator_batch_js,
  relative_strength_index_wave_indicator_alloc,
  relative_strength_index_wave_indicator_free,
  relative_strength_index_wave_indicator_into,
  relative_strength_index_wave_indicator_batch_into,
} from "vector-ta-wasm";

await init();

const out = relative_strength_index_wave_indicator_js(
  source,
  high,
  low,
  14,
  2,
  5,
  9,
  13,
);

console.log(out.rsi_ma1, out.state);

const batch = relative_strength_index_wave_indicator_batch_js(source, high, low, {
  rsi_length_range: [10, 14, 2],
  length1_range: [2, 4, 2],
  length2_range: [5, 9, 2],
  length3_range: [9, 13, 2],
  length4_range: [13, 17, 2],
});

console.log(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