Acceleration/Deceleration Oscillator (AC)
Overview
The Acceleration/Deceleration Oscillator (AC) is a second-derivative momentum indicator that measures the rate of change of the Awesome Oscillator. It calculates the difference between the AO (which itself is the difference between 5-period and 34-period SMAs of median price) and a 5-period SMA of the AO.
The AC provides two output arrays: the oscillator values and the momentum change between consecutive values. With fixed periods of 5 and 34 for the underlying Awesome Oscillator calculation and an additional 5-period smoothing, the indicator requires a minimum of 39 data points to produce valid results.
Implementation Examples
Get started with ACOSC in just a few lines:
use vectorta::indicators::acosc::{acosc, AcoscInput, AcoscParams};
use vectorta::utilities::data_loader::Candles;
// Using with high/low price slices
let high = vec![100.0, 102.0, 101.5, 103.0, 105.0, 104.5];
let low = vec![99.0, 98.0, 99.5, 100.0, 102.0, 103.0];
let params = AcoscParams::default(); // No configurable parameters
let input = AcoscInput::from_slices(&high, &low, params);
let result = acosc(&input)?;
// Using with Candles data structure
// Quick and simple with default parameters
let input = AcoscInput::with_default_candles(&candles);
let result = acosc(&input)?;
// Access the oscillator and change values
for (osc, change) in result.osc.iter().zip(result.change.iter()) {
println!("AC: {}, Change: {}", osc, change);
} API Reference
Input Methods ▼
// From high/low slices
AcoscInput::from_slices(&[f64], &[f64], AcoscParams) -> AcoscInput
// From candles
AcoscInput::from_candles(&Candles, AcoscParams) -> AcoscInput
// From candles with default params
AcoscInput::with_default_candles(&Candles) -> AcoscInput Parameters Structure ▼
pub struct AcoscParams {} // Empty - ACOSC uses fixed parameters
// Fixed internal parameters:
// - Fast SMA period: 5
// - Slow SMA period: 34
// - Signal smoothing period: 5 Output Structure ▼
pub struct AcoscOutput {
pub osc: Vec<f64>, // AC oscillator values
pub change: Vec<f64>, // Momentum change between consecutive AC values
} Error Handling ▼
use vectorta::indicators::acosc::AcoscError;
match acosc(&input) {
Ok(output) => {
process_results(output.osc, output.change);
},
Err(AcoscError::CandleFieldError { msg }) =>
println!("Failed to get high/low from candles: {}", msg),
Err(AcoscError::LengthMismatch { high_len, low_len }) =>
println!("High/low length mismatch: {} vs {}", high_len, low_len),
Err(AcoscError::NotEnoughData { required, actual }) =>
println!("Need {} data points, only {} available", required, actual),
Err(e) => println!("ACOSC error: {}", e)
} Python Bindings
Basic Usage ▼
Calculate ACOSC using NumPy arrays:
import numpy as np
from vectorta import acosc
# Prepare high/low price data as NumPy arrays
high = np.array([100.0, 102.0, 101.5, 103.0, 105.0, 104.5])
low = np.array([99.0, 98.0, 99.5, 100.0, 102.0, 103.0])
# Calculate ACOSC (fixed parameters: 5/34 for AO, 5 for signal)
osc, change = acosc(high, low)
# Specify kernel for performance optimization
osc, change = acosc(high, low, kernel="avx2")
# Results are NumPy arrays matching input length
print(f"AC Oscillator: {osc}")
print(f"Momentum Change: {change}")
# The change array represents momentum between consecutive AC values
positive_momentum = change > 0
print(f"Periods with increasing momentum: {np.sum(positive_momentum)}") Streaming Real-time Updates ▼
Process real-time price updates efficiently:
from vectorta import AcoscStream
# Initialize streaming ACOSC calculator
stream = AcoscStream()
# Process real-time price updates
for high, low in price_feed:
result = stream.update(high, low)
if result is not None:
osc_value, change_value = result
# AC values are ready (None during 39-bar warmup period)
print(f"Current AC: {osc_value}, Change: {change_value}")
# Monitor momentum changes
if change_value > 0:
print("Momentum is accelerating")
else:
print("Momentum is decelerating") Batch Processing ▼
Process data with batch optimizations:
import numpy as np
from vectorta import acosc_batch
# Your high/low price data
high = np.array([...]) # Historical high prices
low = np.array([...]) # Historical low prices
# Run batch calculation
# Note: ACOSC has no parameters, so batch returns single row
results = acosc_batch(
high,
low,
kernel="auto" # Auto-select best kernel
)
# Access results
print(f"Oscillator shape: {results['osc'].shape}") # (1, len(prices))
print(f"Change shape: {results['change'].shape}") # (1, len(prices))
# Extract the single row of results
osc_values = results['osc'][0]
change_values = results['change'][0]
# Analyze momentum patterns
momentum_shifts = np.diff(np.sign(change_values))
print(f"Number of momentum direction changes: {np.sum(momentum_shifts != 0)}") CUDA Acceleration ▼
CUDA support for ACOSC is currently under development. The API will follow the same pattern as other CUDA-enabled indicators.
# Coming soon: CUDA-accelerated ACOSC calculations
#
# from vectorta import acosc_cuda_batch, acosc_cuda_many_series_one_param
# import numpy as np
#
# # Since ACOSC has no parameters, only the "many series" pattern applies
#
# # Process multiple stocks/assets with ACOSC
# # Shape: [time_steps, num_assets]
# portfolio_highs = np.array([...])
# portfolio_lows = np.array([...])
#
# osc_results, change_results = acosc_cuda_many_series(
# high_tm=portfolio_highs, # Time-major format [T, N]
# low_tm=portfolio_lows, # Time-major format [T, N]
# device_id=0
# )
# # Returns: Two 2D arrays [time_steps, num_assets]
# # - osc_results: AC oscillator for each asset
# # - change_results: momentum change for each asset
#
# # Zero-copy variant with pre-allocated output (F32 for GPU efficiency)
# osc_out = np.empty((time_steps, num_assets), dtype=np.float32)
# change_out = np.empty((time_steps, num_assets), dtype=np.float32)
# acosc_cuda_many_series_into(
# high_tm_f32=portfolio_highs.astype(np.float32),
# low_tm_f32=portfolio_lows.astype(np.float32),
# osc_out=osc_out,
# change_out=change_out,
# device_id=0
# ) JavaScript/WASM Bindings
Basic Usage ▼
Calculate ACOSC in JavaScript/TypeScript:
import { acosc_js } from 'vectorta-wasm';
// High/low price data as Float64Array or regular array
const high = new Float64Array([100.0, 102.0, 101.5, 103.0, 105.0, 104.5]);
const low = new Float64Array([99.0, 98.0, 99.5, 100.0, 102.0, 103.0]);
// Calculate ACOSC (fixed parameters)
const result = acosc_js(high, low);
// Result is a flattened Float64Array [osc_values..., change_values...]
const len = high.length;
const osc = result.slice(0, len);
const change = result.slice(len);
console.log('AC Oscillator:', osc);
console.log('Momentum Change:', change);
// TypeScript type definitions
interface AcoscResult {
osc: Float64Array;
change: Float64Array;
}
// Helper function to parse results
function parseAcoscResult(result: Float64Array, length: number): AcoscResult {
return {
osc: result.slice(0, length),
change: result.slice(length)
};
} Memory-Efficient Operations ▼
Use zero-copy operations for better performance with large datasets:
import { acosc_alloc, acosc_free, acosc_into, memory } from 'vectorta-wasm';
// Prepare your high/low data
const high = new Float64Array([/* your data */]);
const low = new Float64Array([/* your data */]);
const length = high.length;
// Allocate WASM memory for outputs
const oscPtr = acosc_alloc(length);
const changePtr = acosc_alloc(length);
// Get input data pointers in WASM memory
const highArray = new Float64Array(memory.buffer, /* offset */, length);
const lowArray = new Float64Array(memory.buffer, /* offset */, length);
highArray.set(high);
lowArray.set(low);
// Calculate ACOSC directly into allocated memory (zero-copy)
acosc_into(
highArray.byteOffset, // High prices pointer
lowArray.byteOffset, // Low prices pointer
oscPtr, // Oscillator output pointer
changePtr, // Change output pointer
length // Data length
);
// Read results from WASM memory
const oscResult = new Float64Array(memory.buffer, oscPtr, length);
const changeResult = new Float64Array(memory.buffer, changePtr, length);
// Convert to regular arrays if needed
const oscValues = Array.from(oscResult);
const changeValues = Array.from(changeResult);
// Important: Free allocated memory when done
acosc_free(oscPtr, length);
acosc_free(changePtr, length);
console.log('AC Oscillator:', oscValues);
console.log('Momentum Change:', changeValues); Batch Processing ▼
Process data with batch optimizations:
import { acosc_batch, acosc_batch_metadata_js } from 'vectorta-wasm';
// Your high/low price data
const high = new Float64Array([/* historical highs */]);
const low = new Float64Array([/* historical lows */]);
// Get metadata (empty for ACOSC since no parameters)
const metadata = acosc_batch_metadata_js();
console.log('Metadata:', metadata); // Returns empty array
// Calculate with batch optimizations
const config = {}; // Empty config since ACOSC has no parameters
const result = acosc_batch(high, low, config);
// Parse the batch result
interface AcoscBatchResult {
values: Float64Array; // Flattened [osc..., change...]
rows: number; // Always 1 for ACOSC
cols: number; // Length of input data
}
const batchResult = result as AcoscBatchResult;
console.log(`Result dimensions: ${batchResult.rows}x${batchResult.cols}`);
// Extract oscillator and change values
const len = batchResult.cols;
const osc = batchResult.values.slice(0, len);
const change = batchResult.values.slice(len);
// Analyze momentum patterns
let momentumShifts = 0;
for (let i = 1; i < change.length; i++) {
if (Math.sign(change[i]) !== Math.sign(change[i-1])) {
momentumShifts++;
}
}
console.log(`Momentum direction changes: ${momentumShifts}`); Performance Analysis
Related Indicators
Awesome Oscillator
Technical analysis indicator
Absolute Price Oscillator
Technical analysis indicator
Commodity Channel Index
Technical analysis indicator
Center of Gravity
Technical analysis indicator
Chande Momentum Oscillator
Technical analysis indicator
Chande Momentum Oscillator
Technical analysis indicator