Reverse Relative Strength Index (Reverse RSI)

Parameters: rsi_length = 14 | rsi_level = 50 (0–100)

Overview

Reverse RSI inverts the traditional RSI formula to calculate what price level would produce a specific RSI reading, given current momentum conditions. While standard RSI transforms prices into a 0 to 100 oscillator, Reverse RSI works backward from a target RSI value to determine the corresponding price. The calculation maintains Wilder smoothing for average gains and losses, then solves algebraically for the next price that would achieve the desired RSI level. This inversion proves valuable for setting price targets based on momentum thresholds, such as determining what price would push RSI into oversold territory below 30 or overbought conditions above 70. Traders use Reverse RSI to establish dynamic support and resistance zones that adapt to changing volatility, or to position protective stops at levels where momentum would clearly reverse. The indicator requires a warmup period of twice the RSI length minus one bar to initialize the smoothing properly.

Defaults: rsi_length=14, rsi_level=50 (close price source).

Implementation Examples

Compute Reverse RSI values from slices or candles:

use vectorta::indicators::reverse_rsi::{reverse_rsi, ReverseRsiInput, ReverseRsiParams};
use vectorta::utilities::data_loader::{Candles, read_candles_from_csv};

// Using with a price data slice
let prices = vec![100.0, 101.0, 99.5, 102.0, 103.0, 104.5, 103.0];
let params = ReverseRsiParams { rsi_length: Some(14), rsi_level: Some(50.0) };
let input = ReverseRsiInput::from_slice(&prices, params);
let out = reverse_rsi(&input)?;

// Using with Candles (defaults: length=14, level=50; source="close")
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let input = ReverseRsiInput::with_default_candles(&candles);
let out = reverse_rsi(&input)?;

// Access the target prices
for v in out.values { println!("ReverseRSI target: {}", v); }

API Reference

Input Methods
// From price slice
ReverseRsiInput::from_slice(&[f64], ReverseRsiParams) -> ReverseRsiInput

// From candles with custom source
ReverseRsiInput::from_candles(&Candles, &str, ReverseRsiParams) -> ReverseRsiInput

// From candles with defaults (close, length=14, level=50)
ReverseRsiInput::with_default_candles(&Candles) -> ReverseRsiInput
Parameters Structure
#[derive(Debug, Clone)]
pub struct ReverseRsiParams {
    pub rsi_length: Option<usize>, // Default: 14
    pub rsi_level: Option<f64>,    // Default: 50.0 (must satisfy 0 < level < 100)
}
Output Structure
#[derive(Debug, Clone)]
pub struct ReverseRsiOutput {
    pub values: Vec<f64>, // Reverse RSI target prices
}
Validation, Warmup & NaNs
  • rsi_length > 0 and rsi_length ≤ input_len; otherwise ReverseRsiError::InvalidPeriod.
  • 0 < rsi_level < 100 and finite; otherwise ReverseRsiError::InvalidRsiLevel.
  • Warmup requires (2*rsi_length−1) valid points after the first finite value; otherwise ReverseRsiError::NotEnoughValidData.
  • Indices before first + (2*rsi_length−2) are NaN. First finite output appears at that index.
  • Non‑finite inputs are treated as no change during diffs. Extremely ill‑conditioned cases may yield 0.0 fallback for out‑of‑range arithmetic.
  • Streaming returns None until warmup completes; then emits a value per update.
Error Handling
use vectorta::indicators::reverse_rsi::{reverse_rsi, ReverseRsiError};

match reverse_rsi(&input) {
    Ok(output) => process(output.values),
    Err(ReverseRsiError::EmptyInputData) => println!("Input is empty"),
    Err(ReverseRsiError::AllValuesNaN) => println!("All values are NaN"),
    Err(ReverseRsiError::InvalidPeriod { period, data_len }) =>
        println!("Invalid period {} for length {}", period, data_len),
    Err(ReverseRsiError::InvalidRsiLevel { level }) =>
        println!("Invalid RSI level: {} (must be 0 < L < 100)", level),
    Err(ReverseRsiError::NotEnoughValidData { needed, valid }) =>
        println!("Need {} valid points after first finite, have {}", needed, valid),
}

Python Bindings

Basic Usage

Calculate Reverse RSI using NumPy arrays (defaults: length=14, level=50):

import numpy as np
from vectorta import reverse_rsi, ReverseRsiStream, reverse_rsi_batch

prices = np.array([100.0, 101.0, 99.5, 102.0, 103.0])

# Basic usage (defaults)
result = reverse_rsi(prices, 14, 50.0)

# Custom with kernel selection ("auto"|"avx2"|"avx512")
result = reverse_rsi(prices, 14, 70.0, kernel="auto")

# Streaming
stream = ReverseRsiStream(14, 50.0)
for p in prices:
    v = stream.update(p)
    if v is not None:
        print(v)

# Batch sweep
out = reverse_rsi_batch(
    prices,
    rsi_length_range=(10, 20, 2),
    rsi_level_range=(30.0, 70.0, 10.0),
    kernel="auto"
)
print(out['values'].shape, out['rsi_lengths'], out['rsi_levels'])
CUDA Acceleration

CUDA support for Reverse RSI is currently under development. The API will follow the same pattern as other CUDA-enabled indicators.

# Coming soon: CUDA-accelerated Reverse RSI calculations
# See APO page for CUDA patterns that will be mirrored here.

JavaScript/WASM Bindings

Basic Usage

Compute Reverse RSI in JavaScript/TypeScript:

import { reverse_rsi_js } from 'vectorta-wasm';

const prices = new Float64Array([100.0, 101.0, 99.5, 102.0, 103.0]);
const values = reverse_rsi_js(prices, 14, 50.0); // length=14, level=50
console.log('ReverseRSI:', values);
Memory-Efficient Operations

Use zero-copy buffers for large datasets:

import { memory, reverse_rsi_alloc, reverse_rsi_free, reverse_rsi_into } from 'vectorta-wasm';

const prices = new Float64Array([/* your data */]);
const len = prices.length;

const inPtr = reverse_rsi_alloc(len);
const outPtr = reverse_rsi_alloc(len);

new Float64Array(memory.buffer, inPtr, len).set(prices);
reverse_rsi_into(inPtr, outPtr, len, 14, 50.0);

const out = new Float64Array(memory.buffer, outPtr, len).slice();
reverse_rsi_free(inPtr, len);
reverse_rsi_free(outPtr, len);
Batch Processing

Sweep parameter combinations in the browser:

import { reverse_rsi_batch } from 'vectorta-wasm';

const prices = new Float64Array([/* data */]);
const config = {
  rsi_length_range: [10, 20, 2],
  rsi_level_range: [30.0, 70.0, 10.0],
};
const out = reverse_rsi_batch(prices, config);
// out = { values: Float64Array, combos: {rsi_length?, rsi_level?}[], rows, cols }

Performance Analysis

Comparison:
View:
Loading chart...

AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU) | Benchmarks: 2026-01-05

Related Indicators