2.6 KiB
ADL - Accumulation/Distribution Line
The Accumulation/Distribution Line (ADL) measures the cumulative flow of money into and out of a security. It validates price trends by correlating volume with price close location within the high-low range.
Architectural Design
We implement ADL as a stateful, streaming accumulator that maintains O(1) complexity for each new data point. Unlike window-based indicators, ADL carries its entire history in a single double-precision state variable.
The "Close Location Value" (CLV)
The core mechanic relies on the Money Flow Multiplier (MFM), also known as CLV. This value ranges from -1 to +1:
- +1: Close equals High (Maximum Accumulation)
- -1: Close equals Low (Maximum Distribution)
- 0: Close is exactly between High and Low
This approach avoids the noise of simple price changes, focusing instead on where the price settles relative to its intraday range.
MFM = \frac{(Close - Low) - (High - Close)}{High - Low}
MFV = MFM \times Volume
ADL_{current} = ADL_{previous} + MFV
Zero-Allocation Implementation
Our implementation processes updates without heap allocations. The state consists of a single double _lastAdl.
- Complexity: O(1) per update.
- Memory: 16 bytes (state) + object overhead.
- NaN Handling: If
High == Low, MFM is 0 to avoid division by zero. If inputs areNaN, the last valid ADL value is preserved.
Usage
Streaming API
The streaming API is designed for real-time event processing. It updates the state with each new bar and returns the latest value immediately.
using QuanTAlib;
// Initialize
var adl = new Adl();
// Update loop
foreach (var bar in feed)
{
var result = adl.Update(bar);
Console.WriteLine($"ADL: {result.Value:F2}");
}
Batch Processing
For historical analysis, the static Calculate method processes full datasets using optimized loops.
var bars = GetHistory();
var adlSeries = Adl.Calculate(bars);
Performance Benchmarks
Processing 10,000 bars on an Intel Core i9-13900K:
| Operation | Time | Allocations |
|---|---|---|
| Update (Single) | 2.1 ns | 0 bytes |
| Calculate (Batch) | 15 μs | 0 bytes (excluding output) |
Validation
We validate correctness against three external authorities to 1e-9 precision:
| Library | Status | Notes |
|---|---|---|
| Skender.Stock.Indicators | ✅ Pass | Reference implementation |
| TA-Lib | ✅ Pass | Matches AD function |
| Tulip Indicators | ✅ Pass | Matches ad indicator |
See Validation for comprehensive test results.