Accumulation Swing Index (ASI)
daily_limit = 10000 Overview
Accumulation Swing Index is the cumulative form of Welles Wilder's Swing Index. Instead of treating each bar as a standalone swing-strength reading, the indicator adds each new swing increment onto a running total so that the output behaves more like a trend-confirmation line. Rising ASI implies that upward swing pressure is dominating over time, while falling ASI implies the opposite.
The VectorTA implementation uses the previous bar's open and close together with the current bar's open, high, low, and close to calculate each increment. The daily limit parameter controls the normalization scale for those increments. The line starts at zero on the first valid bar, then accumulates forward. Non-finite bars are passed through as gaps, but the prior open/close state still advances with the incoming data so later bars continue from the updated context rather than restarting a brand-new regime.
Defaults: Accumulation Swing Index uses `daily_limit = 10000.0`.
Implementation Examples
Compute ASI from OHLC slices or directly from a candle container.
use vector_ta::indicators::accumulation_swing_index::{
accumulation_swing_index,
AccumulationSwingIndexInput,
AccumulationSwingIndexParams,
};
use vector_ta::utilities::data_loader::{Candles, read_candles_from_csv};
let open = vec![100.0, 101.4, 102.1, 101.8, 103.0, 104.2];
let high = vec![101.2, 102.6, 102.8, 103.4, 104.1, 105.0];
let low = vec![99.4, 100.7, 101.1, 101.0, 102.0, 103.6];
let close = vec![100.9, 102.0, 101.5, 103.0, 103.7, 104.4];
let output = accumulation_swing_index(&AccumulationSwingIndexInput::from_slices(
&open,
&high,
&low,
&close,
AccumulationSwingIndexParams {
daily_limit: Some(10_000.0),
},
))?;
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let candle_output = accumulation_swing_index(
&AccumulationSwingIndexInput::with_default_candles(&candles)
)?;
println!("Latest ASI: {:?}", output.values.last());
println!("Candle ASI length: {}", candle_output.values.len()); API Reference
Input Methods ▼
// From candles
AccumulationSwingIndexInput::from_candles(&Candles, AccumulationSwingIndexParams)
-> AccumulationSwingIndexInput
// From OHLC slices
AccumulationSwingIndexInput::from_slices(
&[f64],
&[f64],
&[f64],
&[f64],
AccumulationSwingIndexParams,
) -> AccumulationSwingIndexInput
// From candles with default parameters
AccumulationSwingIndexInput::with_default_candles(&Candles)
-> AccumulationSwingIndexInput Parameters Structure ▼
pub struct AccumulationSwingIndexParams {
pub daily_limit: Option<f64>, // default 10000.0
} Output Structure ▼
pub struct AccumulationSwingIndexOutput {
pub values: Vec<f64>,
} Validation, Warmup & NaNs ▼
- All four OHLC slices must be non-empty and share the same length, otherwise the function returns
EmptyInputDataorInconsistentSliceLengths. - If no fully finite OHLC bar exists, the function returns
AllValuesNaN. daily_limitmust be finite and greater than zero.- The output is prefixed with
NaNvalues until the first fully finite bar. The first valid bar itself is set to0.0, and accumulation starts from the second valid bar onward. - Internal swing increments are skipped when the current or prior reference bars are non-finite, but the previous open and close state still rolls forward with the incoming data.
- Batch mode only accepts batch-capable kernels in
accumulation_swing_index_batch_with_kernel.
Builder, Streaming & Batch APIs ▼
// Builder
AccumulationSwingIndexBuilder::new()
.daily_limit(f64)
.kernel(Kernel)
.apply_slices(&[f64], &[f64], &[f64], &[f64])
AccumulationSwingIndexBuilder::new()
.apply(&Candles)
AccumulationSwingIndexBuilder::new()
.into_stream()
// Stream
AccumulationSwingIndexStream::try_new(AccumulationSwingIndexParams)
AccumulationSwingIndexStream::update(open, high, low, close) -> f64
// Batch
AccumulationSwingIndexBatchBuilder::new()
.daily_limit_range(f64, f64, f64)
.kernel(Kernel)
.apply_slices(&[f64], &[f64], &[f64], &[f64]) Error Handling ▼
pub enum AccumulationSwingIndexError {
EmptyInputData,
AllValuesNaN,
InconsistentSliceLengths { open_len: usize, high_len: usize, low_len: usize, close_len: usize },
InvalidDailyLimit { daily_limit: f64 },
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 binding returns a NumPy array of ASI values. Batch returns a dictionary with a 2D values matrix plus the tested daily-limit axis and the final rows/cols shape. The stream returns the latest accumulated line value for each update.
import numpy as np
from vector_ta import (
accumulation_swing_index,
accumulation_swing_index_batch,
AccumulationSwingIndexStream,
)
open_ = np.asarray(open_values, dtype=np.float64)
high = np.asarray(high_values, dtype=np.float64)
low = np.asarray(low_values, dtype=np.float64)
close = np.asarray(close_values, dtype=np.float64)
values = accumulation_swing_index(
open_,
high,
low,
close,
daily_limit=10000.0,
kernel="auto",
)
batch = accumulation_swing_index_batch(
open_,
high,
low,
close,
daily_limit_range=(8000.0, 12000.0, 2000.0),
kernel="auto",
)
stream = AccumulationSwingIndexStream(10000.0)
print(stream.update(open_[-1], high[-1], low[-1], close[-1])) JavaScript/WASM Bindings
The WASM wrapper exposes array-returning single-run and batch functions plus lower-level allocation and in-place APIs. The simple JavaScript entry point returns one ASI array. Batch accepts a three-element daily-limit range in its config object and returns the flattened values matrix together with the tested daily limits and shape.
import init, {
accumulation_swing_index_js,
accumulation_swing_index_batch_js,
} from "/pkg/vector_ta.js";
await init();
const open = new Float64Array(openValues);
const high = new Float64Array(highValues);
const low = new Float64Array(lowValues);
const close = new Float64Array(closeValues);
const values = accumulation_swing_index_js(open, high, low, close, 10000.0);
console.log(values.at(-1));
const batch = accumulation_swing_index_batch_js(open, high, low, close, {
daily_limit_range: [8000.0, 12000.0, 2000.0],
});
console.log(batch.rows, batch.cols, batch.daily_limits); 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)