Inverse Fisher Transform RSI (IFT-RSI)
rsi_period = 5 | wma_period = 9 Overview
The Inverse Fisher Transform RSI amplifies momentum signals by applying a hyperbolic tangent transformation to smoothed RSI values, creating an oscillator that snaps decisively to extremes rather than lingering in neutral zones like traditional momentum indicators. First calculating RSI with Wilder's smoothing, then applying weighted moving average smoothing, the indicator finally transforms these values through the inverse Fisher function to produce sharp, binary signals bounded between -1 and +1. When IFT-RSI approaches +1, it signals powerful bullish momentum that often coincides with breakout acceleration, while readings near -1 indicate intense selling pressure typically found at capitulation lows. The transformation compresses middle values while expanding extremes, eliminating the ambiguous 40 to 60 RSI range where traditional momentum indicators provide unclear signals, instead forcing clear overbought or oversold readings. Traders appreciate IFT-RSI for its ability to identify momentum exhaustion points with precision, as the indicator tends to flatline at extremes just before reversals, providing earlier exit signals than gradual RSI divergences. Additionally, the double smoothing process filters out minor fluctuations while the Fisher transformation ensures rapid response to genuine momentum shifts, creating cleaner signals for both mean reversion and trend continuation strategies.
Implementation Examples
Get started with IFT‑RSI in just a few lines:
use vectorta::indicators::ift_rsi::{ift_rsi, IftRsiInput, IftRsiParams};
use vectorta::utilities::data_loader::{Candles, read_candles_from_csv};
// Using with price data slice
let prices = vec![100.0, 102.0, 101.5, 103.0, 105.0, 104.5];
let params = IftRsiParams {
rsi_period: Some(5),
wma_period: Some(9),
};
let input = IftRsiInput::from_slice(&prices, params);
let result = ift_rsi(&input)?;
// Using with Candles data structure
// Quick and simple with default parameters (rsi=5, wma=9; source="close")
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let input = IftRsiInput::with_default_candles(&candles);
let result = ift_rsi(&input)?;
// Access the IFT-RSI values
for value in result.values {
println!("IFT-RSI: {}", value);
} API Reference
Input Methods ▼
// From price slice
IftRsiInput::from_slice(&[f64], IftRsiParams) -> IftRsiInput
// From candles with custom source
IftRsiInput::from_candles(&Candles, &str, IftRsiParams) -> IftRsiInput
// From candles with default params (close prices, rsi=5, wma=9)
IftRsiInput::with_default_candles(&Candles) -> IftRsiInput Parameters Structure ▼
pub struct IftRsiParams {
pub rsi_period: Option<usize>, // Default: 5
pub wma_period: Option<usize>, // Default: 9
} Output Structure ▼
pub struct IftRsiOutput {
pub values: Vec<f64>, // IFT-RSI values in [-1, 1]
} Validation, Warmup & NaNs ▼
rsi_period > 0,wma_period > 0, and each must be<= len; otherwiseIftRsiError::InvalidPeriod.- Requires at least
max(rsi_period, wma_period)valid points after first finite; elseIftRsiError::NotEnoughValidData. - Warmup prefix length:
first_non_nan + rsi_period + wma_period − 1; indices before areNaN. - Streaming: returns
Noneuntil RSI seed and WMA window are ready; then returnstanh(WMA(0.1·(RSI−50)))per update. - Leading
NaNs delay the first value; subsequentNaNs in inputs are handled by computing from the first finite segment.
Error Handling ▼
use vectorta::indicators::ift_rsi::{ift_rsi, IftRsiError};
match ift_rsi(&input) {
Ok(output) => process_results(output.values),
Err(IftRsiError::EmptyData) => eprintln!("empty input"),
Err(IftRsiError::AllValuesNaN) => eprintln!("all values are NaN"),
Err(IftRsiError::InvalidPeriod { rsi_period, wma_period, data_len }) => {
eprintln!("invalid periods: rsi={}, wma={}, len={}", rsi_period, wma_period, data_len)
}
Err(IftRsiError::NotEnoughValidData { needed, valid }) => {
eprintln!("need {} valid points, only {}", needed, valid)
}
Err(IftRsiError::RsiCalculationError(e)) => eprintln!("RSI error: {}", e),
Err(IftRsiError::WmaCalculationError(e)) => eprintln!("WMA error: {}", e),
Err(IftRsiError::LengthMismatch { dst_len, data_len }) => {
eprintln!("dst_len={} != data_len={}", dst_len, data_len)
}
Err(IftRsiError::WrongKernelForBatch) => eprintln!("use a batch kernel for batch ops"),
} Python Bindings
Basic Usage ▼
Calculate IFT‑RSI using NumPy arrays (required args: rsi_period, wma_period):
import numpy as np
from vectorta import ift_rsi
# Prepare price data as NumPy array
prices = np.array([100.0, 102.0, 101.5, 103.0, 105.0, 104.5])
# Calculate IFT-RSI with typical Ehlers defaults (5/9)
result = ift_rsi(prices, rsi_period=5, wma_period=9)
# Specify kernel for performance optimization
result = ift_rsi(prices, rsi_period=5, wma_period=9, kernel="avx2")
print(f"IFT-RSI values: {result}") Streaming Real-time Updates ▼
Process real-time price updates efficiently:
from vectorta import IftRsiStream
# Initialize streaming IFT-RSI calculator
stream = IftRsiStream(rsi_period=5, wma_period=9)
# Process real-time price updates
for price in price_feed:
value = stream.update(price)
if value is not None:
print(f"Current IFT-RSI: {value}") Batch Parameter Optimization ▼
Test multiple parameter combinations:
import numpy as np
from vectorta import ift_rsi_batch
prices = np.array([...])
# Define parameter ranges: (start, end, step)
rsi_range = (3, 14, 1)
wma_range = (5, 21, 2)
results = ift_rsi_batch(
prices,
rsi_period_range=rsi_range,
wma_period_range=wma_range,
kernel="auto"
)
print(results["values"].shape) # (rows, len(prices))
print(results["rsi_periods"], results["wma_periods"]) CUDA Acceleration ▼
CUDA support for IFT‑RSI is currently under development. The API will follow the same pattern as other CUDA‑enabled indicators.
# Coming soon: CUDA-accelerated IFT-RSI calculations
# Pattern will mirror other CUDA-enabled indicators in vectorta
# (batch parameter sweeps and many-series kernels). JavaScript/WASM Bindings
Basic Usage ▼
Calculate IFT‑RSI in JavaScript/TypeScript:
import { ift_rsi_js } from 'vectorta-wasm';
// Price data as Float64Array or regular array
const prices = new Float64Array([100.0, 102.0, 101.5, 103.0, 105.0, 104.5]);
// Calculate IFT-RSI with specified parameters
const result = ift_rsi_js(prices, 5, 9); // rsi=5, wma=9
console.log('IFT-RSI values:', result); Memory-Efficient Operations ▼
Use zero-copy operations for large datasets:
import { ift_rsi_alloc, ift_rsi_free, ift_rsi_into, memory } from 'vectorta-wasm';
const prices = new Float64Array([/* your data */]);
const length = prices.length;
// Allocate WASM memory for input and output
const inPtr = ift_rsi_alloc(length);
const outPtr = ift_rsi_alloc(length);
// Copy input data into WASM memory
new Float64Array(memory.buffer, inPtr, length).set(prices);
// Calculate directly into allocated memory
// Args: in_ptr, out_ptr, len, rsi_period, wma_period
ift_rsi_into(inPtr, outPtr, length, 5, 9);
// Read results (slice() to copy out)
const iftValues = new Float64Array(memory.buffer, outPtr, length).slice();
// Free allocated memory when done
ift_rsi_free(inPtr, length);
ift_rsi_free(outPtr, length);
console.log('IFT-RSI values:', iftValues); Batch Processing ▼
Test multiple parameter combinations efficiently:
import { ift_rsi_batch } from 'vectorta-wasm';
const prices = new Float64Array([/* historical prices */]);
// Define parameter sweep ranges as [start, end, step]
const config = {
rsi_period_range: [3, 14, 1],
wma_period_range: [5, 21, 2],
};
// Calculate all combinations; returns an object
const out = ift_rsi_batch(prices, config);
// out: { values: Float64Array, combos: Array<{rsi_period?: number, wma_period?: number}>, rows, cols }
console.log('rows x cols:', out.rows, 'x', out.cols);
console.log('combos:', out.combos);
// Reshape flat values per row as needed
const matrix = [];
for (let r = 0; r < out.rows; r++) {
const start = r * out.cols;
matrix.push(out.values.slice(start, start + out.cols));
}
// Access a particular combination's series
const firstComboValues = matrix[0]; Performance Analysis
AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU) | Benchmarks: 2026-01-05