Multi-Length Stochastic Average
length = 14 | presmooth = 10 | premethod = sma | postsmooth = 10 | postmethod = sma Overview
Multi-Length Stochastic Average turns one price source into a composite stochastic oscillator. It can pre-smooth the source first, then for each bar it measures where the newest pre-smoothed value sits inside every rolling min-max window from length 4 up to the configured maximum length, averages those normalized readings, and scales the result to a 0 to 100 range.
An optional post-smoothing stage can then smooth that averaged stochastic output again. Candle mode defaults to `close`, smoothing method names are normalized to lowercase, and the streaming implementation resets when it receives a non-finite input or when the current rolling range collapses to zero.
Defaults: `length = 14`, `presmooth = 10`, `premethod = "sma"`, `postsmooth = 10`, `postmethod = "sma"`, and candle input defaults to `close`.
Implementation Examples
Run the indicator on a raw slice or on candle data with the default close source.
use vector_ta::indicators::multi_length_stochastic_average::{
multi_length_stochastic_average,
MultiLengthStochasticAverageInput,
MultiLengthStochasticAverageParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
let close = vec![101.0, 101.8, 102.4, 101.9, 103.1, 104.0, 103.6, 104.8];
let output = multi_length_stochastic_average(&MultiLengthStochasticAverageInput::from_slice(
&close,
MultiLengthStochasticAverageParams::default(),
))?;
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let candle_output = multi_length_stochastic_average(
&MultiLengthStochasticAverageInput::with_default_candles(&candles),
)?;
println!("{:?}", output.values.last());
println!("{}", candle_output.values.len()); API Reference
Input Methods ▼
// From candles and a named source field
MultiLengthStochasticAverageInput::from_candles(
&Candles,
&str,
MultiLengthStochasticAverageParams,
) -> MultiLengthStochasticAverageInput
// From a raw slice
MultiLengthStochasticAverageInput::from_slice(
&[f64],
MultiLengthStochasticAverageParams,
) -> MultiLengthStochasticAverageInput
// From candles with defaults
MultiLengthStochasticAverageInput::with_default_candles(&Candles)
-> MultiLengthStochasticAverageInput Parameters Structure ▼
pub struct MultiLengthStochasticAverageParams {
pub length: Option<usize>, // default 14, minimum 4
pub presmooth: Option<usize>, // default 10, minimum 1
pub premethod: Option<String>, // none | sma | tma | lsma
pub postsmooth: Option<usize>, // default 10, minimum 1
pub postmethod: Option<String>, // none | sma | tma | lsma
} Output Structure ▼
pub struct MultiLengthStochasticAverageOutput {
pub values: Vec<f64>,
} Validation, Warmup & NaNs ▼
- The input slice must be non-empty and contain at least one finite value.
lengthmust be at least4and cannot exceed the input length.presmoothandpostsmoothmust both be greater than0.- Supported smoothing methods are
none,sma,tma, andlsma; method names are canonicalized to lowercase. - Total warmup is
pre_warmup + (length - 1) + post_warmup, wherenone -> 0,smaandlsma -> method_length - 1, andtma -> 2 * (method_length - 1). - Single-run mode requires at least
total_warmup + 1consecutive finite values; output slots before the warmup point areNaN. - Streaming resets on non-finite input and also resets the post-smoother if the current rolling max and min are effectively equal.
- Batch range expansion accepts ascending or descending integer ranges, but a zero step is only valid when the start and end are the same.
Builder, Streaming & Batch APIs ▼
// Builder
MultiLengthStochasticAverageBuilder::new()
.length(usize)
.presmooth(usize)
.premethod(impl Into<String>)
.postsmooth(usize)
.postmethod(impl Into<String>)
.kernel(Kernel)
.apply_slice(&[f64])
MultiLengthStochasticAverageBuilder::new()
.apply(&Candles, &str)
MultiLengthStochasticAverageBuilder::new()
.into_stream()
// Stream
MultiLengthStochasticAverageStream::try_new(MultiLengthStochasticAverageParams)
MultiLengthStochasticAverageStream::update(f64) -> Option<f64>
MultiLengthStochasticAverageStream::get_warmup_period() -> usize
MultiLengthStochasticAverageStream::reset()
// Batch
MultiLengthStochasticAverageBatchBuilder::new()
.length_range(start, end, step)
.presmooth_range(start, end, step)
.postsmooth_range(start, end, step)
.premethod(impl Into<String>)
.postmethod(impl Into<String>)
.kernel(Kernel)
.apply_slice(&[f64])
MultiLengthStochasticAverageBatchBuilder::new()
.apply_candles(&Candles, &str) Error Handling ▼
pub enum MultiLengthStochasticAverageError {
EmptyInputData,
AllValuesNaN,
InvalidLength { length: usize, data_len: usize },
InvalidPresmooth { presmooth: usize },
InvalidPostsmooth { postsmooth: usize },
InvalidPreMethod { premethod: String },
InvalidPostMethod { postmethod: String },
NotEnoughValidData { needed: usize, valid: usize },
OutputLengthMismatch { expected: usize, got: usize },
InvalidRange { start: String, end: String, step: String },
InvalidKernelForBatch(Kernel),
} Python Bindings
Python exposes a NumPy-returning single-run function, a streaming class with a warmup_period property, and a batch function that returns the output matrix plus the parameter grid used for each row.
import numpy as np
from vector_ta import (
multi_length_stochastic_average,
multi_length_stochastic_average_batch,
MultiLengthStochasticAverageStream,
)
data = np.asarray(close_values, dtype=np.float64)
values = multi_length_stochastic_average(
data,
length=14,
presmooth=10,
premethod="sma",
postsmooth=10,
postmethod="sma",
kernel="auto",
)
stream = MultiLengthStochasticAverageStream(
length=14,
presmooth=10,
premethod="sma",
postsmooth=10,
postmethod="lsma",
)
print(stream.warmup_period)
print(stream.update(data[-1]))
batch = multi_length_stochastic_average_batch(
data,
length_range=(14, 20, 2),
presmooth_range=(5, 15, 5),
premethod="sma",
postsmooth_range=(5, 10, 5),
postmethod="lsma",
kernel="auto",
)
print(batch["values"].shape)
print(batch["lengths"])
print(batch["premethods"])
print(batch["rows"], batch["cols"]) JavaScript/WASM Bindings
The WASM layer exposes an object-returning scalar wrapper, an object-returning batch wrapper, and lower-level alloc, free, into, and batch_into exports. The scalar wrapper returns an object with a single values array, while batch adds the flattened matrix, per-row parameter arrays, combos, and the rows and cols shape.
import init, {
multi_length_stochastic_average_js,
multi_length_stochastic_average_batch_js,
} from "/pkg/vector_ta.js";
await init();
const data = new Float64Array(closeValues);
const single = multi_length_stochastic_average_js(
data,
14,
10,
"sma",
10,
"sma",
);
console.log(single.values);
const batch = multi_length_stochastic_average_batch_js(data, {
length_range: [14, 20, 2],
presmooth_range: [5, 15, 5],
premethod: "sma",
postsmooth_range: [5, 10, 5],
postmethod: "lsma",
});
console.log(batch.values);
console.log(batch.lengths, batch.presmooths, batch.postsmooths);
console.log(batch.premethods, batch.postmethods);
console.log(batch.combos, 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)