Advance/Decline Line (ADL)
Overview
The Advance/Decline Line is one of the simplest breadth tools in technical analysis: it cumulatively sums each period's net breadth reading and turns that sequence into a running participation line. When the line rises alongside price, breadth is broadly supporting the move. When price keeps advancing while the line flattens or rolls over, participation is thinning and the move is becoming more selective.
In the VectorTA implementation, the core input is a single numeric stream. Used classically, that stream should already be your net advance-minus-decline series. The candle helper is also available, but it simply cumulates the chosen candle field rather than deriving market breadth on its own. Non-finite values break the cumulative segment and cause the next valid value to start a fresh running total.
Defaults: Advance/Decline Line uses no configurable parameters.
Implementation Examples
Feed the indicator a precomputed breadth series, or use a candle field when you explicitly want a cumulative line of that source.
use vector_ta::indicators::advance_decline_line::{
advance_decline_line,
AdvanceDeclineLineInput,
AdvanceDeclineLineParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
let breadth = vec![12.0, -5.0, 18.0, 7.0, -9.0, 4.0];
let output = advance_decline_line(
&AdvanceDeclineLineInput::from_slice(&breadth, AdvanceDeclineLineParams)
)?;
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let candle_output = advance_decline_line(
&AdvanceDeclineLineInput::with_default_candles(&candles)
)?;
println!("ADL values: {:?}", output.values);
println!("Latest candle cumulative value: {:?}", candle_output.values.last()); API Reference
Input Methods ▼
// From candles and a named source field
AdvanceDeclineLineInput::from_candles(&Candles, &str, AdvanceDeclineLineParams)
-> AdvanceDeclineLineInput
// From a precomputed breadth slice
AdvanceDeclineLineInput::from_slice(&[f64], AdvanceDeclineLineParams)
-> AdvanceDeclineLineInput
// From candles with the default source field
AdvanceDeclineLineInput::with_default_candles(&Candles)
-> AdvanceDeclineLineInput Parameters Structure ▼
pub struct AdvanceDeclineLineParams;
// No configurable parameters. Output Structure ▼
pub struct AdvanceDeclineLineOutput {
pub values: Vec<f64>,
} Validation, Warmup & NaNs ▼
- An empty slice returns
EmptyInputData. - If every input value is non-finite, the function returns
AllValuesNaN. - Warmup is zero after the first finite value, because the line starts accumulating immediately.
- Leading non-finite values are preserved as
NaNin the output. - Any non-finite value inside the series writes
NaNat that index and resets the cumulative segment, so the next finite value starts a fresh running total. - Batch mode only accepts batch-capable kernels in
advance_decline_line_batch_with_kernel; otherwise it returnsInvalidKernelForBatch.
Builder, Streaming & Batch APIs ▼
// Builder
AdvanceDeclineLineBuilder::new()
.kernel(Kernel)
.apply_slice(&[f64])
AdvanceDeclineLineBuilder::new()
.kernel(Kernel)
.apply(&Candles, &str)
AdvanceDeclineLineBuilder::new()
.into_stream()
// Stream
AdvanceDeclineLineStream::try_new()
AdvanceDeclineLineStream::update(f64) -> Option<f64>
AdvanceDeclineLineStream::get_warmup_period() -> usize
// Batch
AdvanceDeclineLineBatchBuilder::new()
.kernel(Kernel)
.apply_slice(&[f64])
AdvanceDeclineLineBatchBuilder::new()
.apply_candles(&Candles, &str) Error Handling ▼
pub enum AdvanceDeclineLineError {
EmptyInputData,
AllValuesNaN,
OutputLengthMismatch { expected: usize, got: usize },
InvalidRange { start: String, end: String, step: String },
InvalidKernelForBatch(Kernel),
} Python Bindings
Python exposes a single-run function, a streaming class, and a batch function. The single-run call returns one NumPy array of cumulative values. Batch returns a dictionary with a single 2D values matrix plus rows and cols, since there are no parameter sweeps. The streaming class returns the updated cumulative value whenever the input is finite and resets on non-finite values.
import numpy as np
from vector_ta import (
advance_decline_line,
advance_decline_line_batch,
AdvanceDeclineLineStream,
)
data = np.asarray([12.0, -5.0, 18.0, 7.0, -9.0, 4.0], dtype=np.float64)
values = advance_decline_line(data, kernel="auto")
print(values)
batch = advance_decline_line_batch(data, kernel="auto")
print(batch["values"], batch["rows"], batch["cols"])
stream = AdvanceDeclineLineStream()
for value in data:
print(stream.update(value)) JavaScript/WASM Bindings
The WASM layer offers both the simple JavaScript wrapper and the raw pointer-based functions. The easiest entry
point is advance_decline_line_js, which returns a typed array of cumulative values.
If you need to manage buffers directly, the module also exposes allocation, free, and in-place functions for
both single-run and batch paths.
import init, {
advance_decline_line_js,
advance_decline_line_batch_js,
} from "/pkg/vector_ta.js";
await init();
const data = new Float64Array([12, -5, 18, 7, -9, 4]);
const values = advance_decline_line_js(data);
console.log(values);
const batch = advance_decline_line_batch_js(data, {});
console.log(batch.values, 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)
Related Indicators
Accumulation/Distribution
Technical analysis indicator
Accumulation/Distribution Oscillator
Technical analysis indicator
Balance of Power
Technical analysis indicator
Chaikin Flow Oscillator
Technical analysis indicator
Detrended Oscillator
Technical analysis indicator
Elder Force Index
Technical analysis indicator