Aroon Oscillator
length = 14 Overview
The Aroon Oscillator simplifies trend analysis by combining Aroon Up and Aroon Down into a single line that oscillates between -100 and +100, calculated as Aroon Up minus Aroon Down. Positive values emerge when recent highs occur more frequently than recent lows, signaling upward momentum with strength proportional to the distance from zero. Conversely, negative readings indicate bearish conditions where new lows dominate the lookback window. The oscillator reaches extreme values near +100 when price consistently makes new highs while avoiding new lows, confirming powerful uptrends worth riding. Zero line crosses provide clear trend change signals without the ambiguity of watching two separate lines converge. Traders use the Aroon Oscillator to filter trades by only taking long positions above zero and shorts below, while avoiding sideways markets when the oscillator fluctuates near zero. The time calculation makes it particularly effective for catching trends early, as it reacts to the frequency of new extremes rather than waiting for price distance confirmations.
Implementation Examples
Get started with the Aroon Oscillator in just a few lines:
use vectorta::indicators::aroonosc::{aroon_osc, AroonOscInput, AroonOscParams};
use vectorta::utilities::data_loader::{Candles, read_candles_from_csv};
// High/low slices must be the same length
let high = vec![
101.2, 102.4, 103.8, 104.6, 105.3, 106.1, 107.0, 106.2,
105.5, 106.8, 107.9, 108.4, 109.1, 108.6, 107.8, 108.9
];
let low = vec![
99.7, 100.5, 101.4, 102.1, 103.0, 104.2, 104.9, 104.0,
103.2, 104.6, 105.7, 106.3, 107.1, 106.4, 105.6, 106.8
];
let params = AroonOscParams { length: Some(14) };
let input = AroonOscInput::from_slices_hl(&high, &low, params);
let output = aroon_osc(&input)?;
// Access the oscillator values
for (idx, value) in output.values.iter().enumerate() {
println!("{idx}: {value}");
}
// Using Candles with defaults (length = 14)
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let input = AroonOscInput::with_default_candles(&candles);
let output = aroon_osc(&input)?; API Reference
Input Methods ▼
// From parallel high/low slices
AroonOscInput::from_slices_hl(&[f64], &[f64], AroonOscParams) -> AroonOscInput
// From Candles (uses high/low columns internally)
AroonOscInput::from_candles(&Candles, AroonOscParams) -> AroonOscInput
// Convenience with default params (length = 14)
AroonOscInput::with_default_candles(&Candles) -> AroonOscInput Parameters Structure ▼
pub struct AroonOscParams {
pub length: Option<usize>, // Default: 14
} Output Structure ▼
pub struct AroonOscOutput {
pub values: Vec<f64>, // Oscillator values in [-100, 100]
} Validation, Warmup & NaNs ▼
length > 0elseAroonOscError::InvalidLength.- Inputs must be same length; otherwise
AroonOscError::MismatchedArrayLengths. - Requires at least
length + 1valid points after the first finite high/low; otherwiseAroonOscError::NotEnoughData. - Warmup: indices
[0 .. first + length)areNaN. First finite output occurs atfirst + length. - Range guarantee: oscillator values are clamped to
[-100, 100]. - Streaming:
AroonOscStream::updatereturnsNoneuntil the window fills, thenSome(value)thereafter.
Error Handling ▼
use vectorta::indicators::aroonosc::AroonOscError;
match aroon_osc(&input) {
Ok(output) => process(output.values),
Err(AroonOscError::InvalidLength { length }) =>
eprintln!("length must be > 0, got {length}"),
Err(AroonOscError::MismatchedArrayLengths { high_len, low_len }) =>
eprintln!("high/low slices differ: {high_len} vs {low_len}"),
Err(AroonOscError::NotEnoughData { required, found }) =>
eprintln!("need {required} observations after warmup, but only {found}"),
Err(AroonOscError::EmptyData) =>
eprintln!("no data available (empty or all non-finite)"),
Err(AroonOscError::InvalidKernel) =>
eprintln!("invalid or non-batch kernel for batch call"),
Err(AroonOscError::InvalidOutputLen { expected, got }) =>
eprintln!("output slice length mismatch: expected {expected}, got {got}"),
Err(e) => eprintln!("Aroon Oscillator failed: {e}"),
} CUDA Acceleration ▼
CUDA support for Aroon Oscillator is currently under development. The API will follow the same pattern as other CUDA-enabled indicators.
# Coming soon: CUDA-accelerated Aroon Oscillator
# Planned batch API will mirror other indicators in this library. Python Bindings
Python bindings coming soon.
JavaScript/WASM Bindings
Basic Usage ▼
Compute the oscillator from browser or Node.js environments:
import { aroonosc_js } from 'vectorta-wasm';
const high = new Float64Array([/* recent highs */]);
const low = new Float64Array([/* matching lows */]);
// length defaults to 14 if omitted
const values = aroonosc_js(high, low, 20);
console.log('Aroon Oscillator values:', values); Memory-Efficient Operations ▼
Use the zero-copy helpers when integrating with WebAssembly memory directly:
import { aroonosc_alloc, aroonosc_free, aroonosc_into, memory } from 'vectorta-wasm';
const high = new Float64Array([/* highs */]);
const low = new Float64Array([/* lows */]);
const length = high.length;
const highPtr = aroonosc_alloc(length);
const lowPtr = aroonosc_alloc(length);
const outPtr = aroonosc_alloc(length);
const highView = new Float64Array(memory.buffer, highPtr, length);
const lowView = new Float64Array(memory.buffer, lowPtr, length);
highView.set(high);
lowView.set(low);
aroonosc_into(
highPtr, // input high pointer
lowPtr, // input low pointer
outPtr, // output pointer
length, // number of samples
14 // length parameter
);
const result = new Float64Array(memory.buffer, outPtr, length);
console.log(result);
// Free allocations when finished
aroonosc_free(highPtr, length);
aroonosc_free(lowPtr, length);
aroonosc_free(outPtr, length); Batch Processing ▼
Evaluate multiple length windows without leaving WASM:
import {
aroonosc_batch_js,
aroonosc_batch_metadata_js,
aroonosc_batch as aroonosc_batch_unified
} from 'vectorta-wasm';
const high = new Float64Array([/* highs */]);
const low = new Float64Array([/* lows */]);
// Legacy flat-array batch helpers
const metadata = aroonosc_batch_metadata_js(10, 40, 5); // [10, 15, 20, 25, 30, 35, 40]
const flatResults = aroonosc_batch_js(high, low, 10, 40, 5);
// Structured API returning values + metadata together
const config = { length_range: [10, 40, 5] };
const { values, combos, rows, cols } = aroonosc_batch_unified(high, low, config);
console.log('rows x cols:', rows, cols);
console.log('first combo length:', combos[0].length); Performance Analysis
Across sizes, Rust CPU runs about 1.08× slower than Tulip C in this benchmark.
AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU) | Benchmarks: 2026-01-05
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
Average Directional Index
Technical analysis indicator
Average Directional Movement Index Rating
Technical analysis indicator
Alligator
Technical analysis indicator
Aroon
Technical analysis indicator
Chande Momentum Oscillator
Technical analysis indicator
Detrended Oscillator
Technical analysis indicator