Random Walk Index
length = 14 Overview
Random Walk Index asks whether recent price movement is stronger than what a random-walk process would be expected to produce over the same number of bars. VectorTA calculates separate high and low series by comparing the current high and low against historical extremes, then normalizing that distance with an ATR estimate scaled by the square root of the lookback.
The result is a two-line trend-strength study rather than a single oscillator. Higher high-line readings indicate upside movement with more directional persistence than a random drift, while higher low-line readings indicate the same on the downside. VectorTA supports candle input, explicit high-low-close slices, streaming updates, and a one-axis batch sweep over the length parameter.
Defaults: `length = 14`.
Implementation Examples
Run the indicator from candles or from explicit high, low, and close slices.
use vector_ta::indicators::random_walk_index::{
random_walk_index,
RandomWalkIndexInput,
RandomWalkIndexParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
let direct = random_walk_index(&RandomWalkIndexInput::from_slices(
&high,
&low,
&close,
RandomWalkIndexParams {
length: Some(14),
},
))?;
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let from_candles = random_walk_index(&RandomWalkIndexInput::with_default_candles(&candles))?;
println!("rwi high = {:?}", direct.high.last());
println!("rwi low = {:?}", from_candles.low.last());API Reference
Input Methods▼
RandomWalkIndexInput::from_candles(&Candles, RandomWalkIndexParams)
-> RandomWalkIndexInput
RandomWalkIndexInput::from_slices(&[f64], &[f64], &[f64], RandomWalkIndexParams)
-> RandomWalkIndexInput
RandomWalkIndexInput::with_default_candles(&Candles)
-> RandomWalkIndexInputParameters Structure▼
pub struct RandomWalkIndexParams {
pub length: Option<usize>, // default 14
}Output Structure▼
pub struct RandomWalkIndexOutput {
pub high: Vec<f64>,
pub low: Vec<f64>,
}Validation & Warmup▼
- High, low, and close slices must all be non-empty, equal in length, and contain at least one valid triple.
lengthmust be greater than0and no larger than the data length.- The vector path requires at least
lengthvalid bars after the first usable triple. - Warmup begins at
first_valid + length - 1, so earlier entries remainNaN. - The stream path returns
(NaN, NaN)until enough data has accumulated. - Batch mode validates the length sweep and rejects non-batch kernels.
Builder, Streaming & Batch APIs▼
RandomWalkIndexBuilder::new()
.length(usize)
.kernel(Kernel)
.apply(&Candles)
.apply_slices(&[f64], &[f64], &[f64])
.into_stream()
RandomWalkIndexStream::try_new(params)
stream.update(high, low, close) -> (f64, f64)
RandomWalkIndexBatchBuilder::new()
.length_range((start, end, step))
.kernel(Kernel)
.apply_candles(&Candles)
.apply_slices(&[f64], &[f64], &[f64])Python Bindings
Python exposes a scalar function returning two NumPy arrays, a streaming class returning the latest high and low RWI values, and a batch helper that returns reshaped matrices plus the resolved length axis.
from vector_ta import (
random_walk_index,
random_walk_index_batch,
RandomWalkIndexStream,
)
single = random_walk_index(high, low, close, length=14)
stream = RandomWalkIndexStream(length=14)
point = stream.update(high[-1], low[-1], close[-1])
batch = random_walk_index_batch(
high,
low,
close,
length_range=(10, 20, 5),
)
print(single["high"][-1], single["low"][-1])
print(batch["lengths"])JavaScript/WASM Bindings
The WASM layer exposes object-returning scalar and batch helpers plus allocation and into-buffer functions for caller-managed memory.
import init, {
random_walk_index_js,
random_walk_index_batch_js,
random_walk_index_alloc,
random_walk_index_free,
random_walk_index_into,
random_walk_index_batch_into,
} from "vector-ta-wasm";
await init();
const single = random_walk_index_js(high, low, close, 14);
const batch = random_walk_index_batch_js(high, low, close, {
length_range: [10, 20, 5],
});
const ptrHigh = random_walk_index_alloc(high.length);
const ptrLow = random_walk_index_alloc(low.length);
const ptrClose = random_walk_index_alloc(close.length);
const ptrOutHigh = random_walk_index_alloc(close.length);
const ptrOutLow = random_walk_index_alloc(close.length);
random_walk_index_into(ptrHigh, ptrLow, ptrClose, ptrOutHigh, ptrOutLow, close.length, 14);
random_walk_index_free(ptrHigh, high.length);
random_walk_index_free(ptrLow, low.length);
random_walk_index_free(ptrClose, close.length);
random_walk_index_free(ptrOutHigh, close.length);
random_walk_index_free(ptrOutLow, close.length);
console.log(single.high, single.low, batch.rows, batch.cols);CUDA Bindings (Rust)
Additional details for the CUDA bindings can be found inside the VectorTA repository.
Performance Analysis
Across sizes, Rust CPU runs about 1.14× faster than Tulip C in this benchmark.
AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU)