Reflex
period = 20 Overview
Reflex detects turning points in price cycles by measuring the difference between smoothed prices and a linear projection, then normalizing this deviation to produce a dimensionless oscillator. The indicator applies a two pole SuperSmoother filter to reduce noise, computes the expected slope over the period window, and divides the difference by an exponentially smoothed variance measure. Values oscillate around zero with spikes appearing at market inflection points while staying flat during steady trends. The normalization ensures readings remain bounded regardless of price scale, making Reflex especially useful for identifying cycle reversals in advance. Traders watch for crossovers through zero as potential entry signals, with positive values suggesting upward momentum and negative values indicating downward pressure. The default 20 period setting balances responsiveness with stability across most timeframes.
Implementation Examples
Get started with Reflex using price slices or candles:
use vector_ta::indicators::reflex::{reflex, ReflexInput, ReflexParams};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
// Using with price data slice
let prices = vec![100.0, 101.2, 100.7, 102.1, 103.0, 102.4];
let params = ReflexParams { period: Some(20) }; // Default is 20 if None
let input = ReflexInput::from_slice(&prices, params);
let out = reflex(&input)?; // ReflexOutput { values: Vec<f64> }
// Using with Candles (defaults: source="close", period=20)
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let input = ReflexInput::with_default_candles(&candles);
let out = reflex(&input)?;
// Access values
for v in out.values { println!("Reflex: {}", v); } API Reference
Input Methods ▼
// From price slice
ReflexInput::from_slice(&[f64], ReflexParams) -> ReflexInput
// From candles with custom source
ReflexInput::from_candles(&Candles, &str, ReflexParams) -> ReflexInput
// From candles with default params (close, period=20)
ReflexInput::with_default_candles(&Candles) -> ReflexInput Parameters Structure ▼
pub struct ReflexParams {
pub period: Option<usize>, // Default: 20
} Output Structure ▼
pub struct ReflexOutput {
pub values: Vec<f64>, // Reflex values
} Validation, Warmup & NaNs ▼
period >= 2;NoDataon empty input;AllValuesNaNif no finite values.- Requires at least
periodvalid points after the first finite value; elseNotEnoughData { needed, found }. - Warmup: the first
periodoutputs are0.0by contract (batch); streaming yieldsNoneuntil warmed. - Normalization uses
mst = 0.04·my_sumt2 + 0.96·mst-1; typical values remain within about ±5.
Error Handling ▼
#[derive(Debug, Error)]
pub enum ReflexError {
NoData,
InvalidPeriod { period: usize },
NotEnoughData { needed: usize, found: usize },
AllValuesNaN,
}
// Example handling
match reflex(&input) {
Ok(out) => {/* use out.values */},
Err(ReflexError::InvalidPeriod { period }) => {/* fix params */},
Err(e) => {/* log or bail */},
} Python Bindings
Basic Usage ▾
Operate on NumPy arrays; optionally pin the kernel.
import numpy as np
from vector_ta import reflex
prices = np.asarray([100.0, 101.2, 100.7, 102.1, 103.0], dtype=np.float64)
values = reflex(prices, period=20)
values_scalar = reflex(prices, period=20, kernel="scalar") Batch Sweeps ▾
Test multiple period values and analyze results:
from vector_ta import reflex_batch
result = reflex_batch(prices, periods=(5, 50, 5), kernel="auto")
values = result["values"] # shape: (rows, len(prices))
periods = result["periods"] # vector of tested periods CUDA Acceleration ▼
CUDA helpers are available when the Python package is built with CUDA support. Inputs must be float32; outputs are device arrays (DLPack / __cuda_array_interface__ compatible).
import numpy as np
from vector_ta import reflex_cuda_batch_dev, reflex_cuda_many_series_one_param_dev
# One series (float32)
data_f32 = np.asarray(load_data(), dtype=np.float32)
dev = reflex_cuda_batch_dev(
data_f32=data_f32,
period_range=(5, 30, 5),
device_id=0,
)
# Many series (time-major)
data_tm_f32 = np.asarray(load_data_time_major_matrix(), dtype=np.float32)
dev_tm = reflex_cuda_many_series_one_param_dev(
data_tm_f32=data_tm_f32,
period=14,
device_id=0,
) JavaScript/WASM Bindings
Basic Usage ▼
Calculate Reflex in JavaScript/TypeScript:
import { reflex_js } from 'vectorta-wasm';
const prices = new Float64Array([100.0, 101.2, 100.7, 102.1, 103.0]);
const result = reflex_js(prices, 20); // period=20
console.log('Reflex values:', result); Memory-Efficient Operations ▼
Use zero-copy operations for better performance with large datasets:
import { reflex_alloc, reflex_free, reflex_into, memory } from 'vectorta-wasm';
const length = prices.length;
const inPtr = reflex_alloc(length);
const outPtr = reflex_alloc(length);
new Float64Array(memory.buffer, inPtr, length).set(prices);
reflex_into(inPtr, outPtr, length, 20);
const values = new Float64Array(memory.buffer, outPtr, length).slice();
reflex_free(inPtr, length);
reflex_free(outPtr, length); Batch Processing ▼
Test multiple period values efficiently:
import { reflex_batch_js, reflex_batch_metadata_js } from 'vectorta-wasm';
const prices = new Float64Array([/* historical prices */]);
const start = 5, end = 50, step = 5;
const meta = reflex_batch_metadata_js(start, end, step); // [p1, p2, ...]
const flat = reflex_batch_js(prices, start, end, step);
const block = prices.length;
const rows = meta.length;
const matrix = [];
for (let i = 0; i < rows; i++) {
matrix.push(flat.slice(i * block, (i + 1) * block));
} CUDA Bindings (Rust)
use vector_ta::cuda::CudaReflex;
use vector_ta::indicators::moving_averages::reflex::ReflexBatchRange;
let cuda = CudaReflex::new(0)?;
let prices: [f32] = /* ... */;
let sweep = ReflexBatchRange::default();
let out = cuda.reflex_batch_dev(&prices, &sweep)?;
let _ = out; Performance Analysis
AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU) | Benchmarks: 2026-02-28
CUDA note
In our benchmark workload, the Rust CPU implementation is faster than CUDA for this indicator. Prefer the Rust/CPU path unless your workload differs.
Related Indicators
Arnaud Legoux Moving Average
Moving average indicator
Compound Ratio Moving Average (CoRa Wave)
Moving average indicator
Centered Weighted Moving Average
Moving average indicator
Double Exponential Moving Average
Moving average indicator
Ehlers Distance Coefficient Filter
Moving average indicator
Ehlers Error-Correcting EMA (ECEMA)
Moving average indicator