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 vector_ta::indicators::aroonosc::{aroon_osc, AroonOscInput, AroonOscParams};
use vector_ta::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 > 0; otherwiseAroonOscError::InvalidPeriod.- Inputs must be the same length; otherwise
AroonOscError::MismatchSliceLength. - Requires at least
length + 1valid points after the first finite high/low; otherwiseAroonOscError::NotEnoughValidData. - 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 vector_ta::indicators::aroonosc::{aroon_osc, AroonOscError};
match aroon_osc(&input) {
Ok(output) => process(output.values),
Err(AroonOscError::EmptyInputData) =>
eprintln!("input data is empty"),
Err(AroonOscError::AllValuesNaN) =>
eprintln!("all input values are NaN"),
Err(AroonOscError::InvalidPeriod { period, data_len }) =>
eprintln!("invalid length: {period} (data_len={data_len})"),
Err(AroonOscError::MismatchSliceLength { high_len, low_len }) =>
eprintln!("high/low slices differ: {high_len} vs {low_len}"),
Err(AroonOscError::NotEnoughValidData { needed, valid }) =>
eprintln!("need {needed} valid points, got {valid}"),
Err(AroonOscError::OutputLengthMismatch { expected, got }) =>
eprintln!("output length mismatch: expected {expected}, got {got}"),
Err(AroonOscError::InvalidKernelForBatch(k)) =>
eprintln!("invalid kernel for batch: {k:?}"),
Err(e) => eprintln!("Aroon Oscillator failed: {e}"),
} 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 aroonosc_cuda_batch_dev, aroonosc_cuda_many_series_one_param_dev
# One series (float32)
high_f32 = np.asarray(load_high(), dtype=np.float32)
low_f32 = np.asarray(load_low(), dtype=np.float32)
dev = aroonosc_cuda_batch_dev(
high_f32=high_f32,
low_f32=low_f32,
length_range=(5, 30, 5),
device_id=0,
)
# Many series (time-major)
high_tm_f32 = np.asarray(load_high_time_major_matrix(), dtype=np.float32)
low_tm_f32 = np.asarray(load_low_time_major_matrix(), dtype=np.float32)
dev_tm = aroonosc_cuda_many_series_one_param_dev(
high_tm_f32=high_tm_f32,
low_tm_f32=low_tm_f32,
length=14,
device_id=0,
) Python Bindings
Quick Start ▼
Compute Aroon Oscillator from NumPy arrays, stream updates, or sweep lengths in batch:
import numpy as np
from vector_ta import aroonosc, aroonosc_batch, AroonOscStream
high = np.asarray([...], dtype=np.float64)
low = np.asarray([...], dtype=np.float64)
# One-shot
values = aroonosc(high, low, length=14, kernel=None)
# Streaming
stream = AroonOscStream(length=14)
for h, l in zip(high, low):
v = stream.update(float(h), float(l))
if v is not None:
handle(v)
# Batch sweep
res = aroonosc_batch(high, low, length_range=(5, 30, 5), kernel=None)
vals = res['values'] 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); CUDA Bindings (Rust)
use vector_ta::cuda::CudaAroonOsc;
use vector_ta::indicators::aroonosc::AroonOscBatchRange;
let cuda = CudaAroonOsc::new(0)?;
let high_f32: [f32] = /* ... */;
let low_f32: [f32] = /* ... */;
let sweep = AroonOscBatchRange::default();
let out = cuda.aroonosc_batch_dev(&high_f32, &low_f32, &sweep)?;
let _ = out; 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-02-28
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