AlphaTrend (AT)
coeff = 1 | period = 14 | no_volume = Overview
AlphaTrend generates dynamic support and resistance levels that adapt to market conditions by combining ATR based volatility bands with momentum filters from either MFI or RSI. The indicator constructs upper and lower bands around price using ATR multiplied by a coefficient, then selects which band becomes the active trend line based on whether momentum exceeds 50. When MFI or RSI rises above 50, AlphaTrend switches to the lower band as support; below 50, it flips to the upper band as resistance. This creates a trailing stop loss line that tightens during strong trends and loosens during consolidations. Traders use AlphaTrend to identify trend direction when price crosses the line, ride trends with the line as a dynamic stop, and spot potential reversals when price repeatedly tests but fails to break through. The indicator outputs both the current trend line and a two bar lagged version, allowing confirmation of crossover signals.
Implementation Examples
Compute AlphaTrend from OHLCV candles or raw slices:
use vectorta::indicators::alphatrend::{alphatrend, AlphaTrendInput, AlphaTrendParams};
use vectorta::utilities::data_loader::{Candles, read_candles_from_csv};
// From OHLCV slices (MFI by default; set no_volume=true to use RSI)
let open = vec![/* ... */];
let high = vec![/* ... */];
let low = vec![/* ... */];
let close = vec![/* ... */];
let volume = vec![/* ... */];
let params = AlphaTrendParams { coeff: Some(1.0), period: Some(14), no_volume: Some(false) };
let input = AlphaTrendInput::from_slices(&open, &high, &low, &close, &volume, params);
let out = alphatrend(&input)?; // out.k1 (current), out.k2 (lagged by 2)
// From Candles with defaults (coeff=1.0, period=14, no_volume=false)
let candles: Candles = read_candles_from_csv("data/sample.csv")?;
let input = AlphaTrendInput::with_default_candles(&candles);
let out = alphatrend(&input)?;
// Access values
println!("k1_last = {:?}, k2_last = {:?}", out.k1.last(), out.k2.last()); API Reference
Input Methods ▼
// From candles (OHLCV)
AlphaTrendInput::from_candles(&Candles, AlphaTrendParams) -> AlphaTrendInput
// From raw OHLCV slices
AlphaTrendInput::from_slices(&[f64], &[f64], &[f64], &[f64], &[f64], AlphaTrendParams) -> AlphaTrendInput
// With defaults (coeff=1.0, period=14, no_volume=false)
AlphaTrendInput::with_default_candles(&Candles) -> AlphaTrendInput Parameters Structure ▼
pub struct AlphaTrendParams {
pub coeff: Option<f64>, // Default: 1.0 (must be > 0)
pub period: Option<usize>,// Default: 14 (>= 1)
pub no_volume: Option<bool>, // Default: false (use MFI)
} Output Structure ▼
pub struct AlphaTrendOutput {
pub k1: Vec<f64>, // Current AlphaTrend line
pub k2: Vec<f64>, // AlphaTrend lagged by 2 bars
} Validation, Warmup & NaNs ▼
len > 0; otherwiseAlphaTrendError::EmptyInputData.- All slices must match length; otherwise
AlphaTrendError::InconsistentDataLengths. - First finite close index must exist; otherwise
AlphaTrendError::AllValuesNaN. period > 0andperiod ≤ len; otherwiseAlphaTrendError::InvalidPeriod.- Need at least
periodvalid points after the first finite close; otherwiseAlphaTrendError::NotEnoughValidData. coeff > 0and finite; otherwiseAlphaTrendError::InvalidCoeff.- Warmup:
k1[0..first+period-1]areNaN;k2additionally lags by 2 bars (NaNuntilwarmup+2). - Momentum errors propagate as
AlphaTrendError::RsiError/AlphaTrendError::MfiError.
Error Handling ▼
use vectorta::indicators::alphatrend::{alphatrend, AlphaTrendError};
match alphatrend(&input) {
Ok(output) => {
use_results(output.k1, output.k2);
}
Err(AlphaTrendError::EmptyInputData) => handle("empty input"),
Err(AlphaTrendError::AllValuesNaN) => handle("all NaN"),
Err(AlphaTrendError::InvalidPeriod { period, data_len }) => handle(&format!("invalid period: {} (len={})", period, data_len)),
Err(AlphaTrendError::NotEnoughValidData { needed, valid }) => handle(&format!("needed {}, had {}", needed, valid)),
Err(AlphaTrendError::InconsistentDataLengths) => handle("inconsistent lengths"),
Err(AlphaTrendError::InvalidCoeff { coeff }) => handle(&format!("invalid coeff: {}", coeff)),
Err(AlphaTrendError::RsiError { msg }) => handle(&format!("RSI failed: {}", msg)),
Err(AlphaTrendError::MfiError { msg }) => handle(&format!("MFI failed: {}", msg)),
} Python Bindings
Compute AlphaTrend ▼
import numpy as np
from vectorta import alphatrend
# OHLCV arrays (float64)
open = np.array([...], dtype=float)
high = np.array([...], dtype=float)
low = np.array([...], dtype=float)
close = np.array([...], dtype=float)
volume = np.array([...], dtype=float)
# coeff=1.0, period=14, no_volume=False (uses MFI); kernel can be "auto", "scalar", "avx2", "avx512"
k1, k2 = alphatrend(open, high, low, close, volume, coeff=1.0, period=14, no_volume=False, kernel="auto")
print(k1[-5:], k2[-5:]) Streaming Real-time Updates ▼
Streaming API exists but update currently returns None (implementation pending).
from vectorta import AlphaTrendStream
stream = AlphaTrendStream(coeff=1.0, period=14, no_volume=False)
for h, l, c, v in ohlcv_stream:
res = stream.update(h, l, c, v)
if res is not None:
k1, k2 = res
print(k1, k2) Batch Parameter Optimization ▼
import numpy as np
from vectorta import alphatrend_batch
open = np.array([...], dtype=float)
high = np.array([...], dtype=float)
low = np.array([...], dtype=float)
close = np.array([...], dtype=float)
volume = np.array([...], dtype=float)
coeff_range = (1.0, 2.0, 0.5) # 1.0, 1.5, 2.0
period_range = (10, 20, 5) # 10, 15, 20
result = alphatrend_batch(open, high, low, close, volume, coeff_range, period_range, no_volume=False, kernel="auto")
print(result["k1"].shape, result["k2"].shape) # (rows, len), (rows, len)
print(result["rows"], result["cols"]) JavaScript/WASM Bindings
Basic Usage ▼
Compute AlphaTrend in JS/TS; result flattens k1 then k2 with metadata.
import { alphatrend_js } from 'vectorta-wasm';
const open = new Float64Array([...]);
const high = new Float64Array([...]);
const low = new Float64Array([...]);
const close = new Float64Array([...]);
const volume = new Float64Array([...]);
const js = alphatrend_js(open, high, low, close, volume, 1.0, 14, false);
// js = { values: Float64Array, rows: 2, cols: N }
const N = js.cols;
const k1 = js.values.slice(0, N);
const k2 = js.values.slice(N, 2*N); Memory-Efficient Operations ▼
Use flat alloc and in-place compute for [k1, k2]:
import { alphatrend_alloc_flat, alphatrend_free_flat, alphatrend_into_flat, memory } from 'vectorta-wasm';
const N = close.length;
const outPtr = alphatrend_alloc_flat(N); // capacity for 2*N doubles
alphatrend_into_flat(openPtr, highPtr, lowPtr, closePtr, volumePtr, outPtr, N, 1.0, 14, false);
const buf = new Float64Array(memory.buffer);
const base = outPtr / Float64Array.BYTES_PER_ELEMENT;
const k1 = buf.slice(base, base + N);
const k2 = buf.slice(base + N, base + 2*N);
alphatrend_free_flat(outPtr, N); Batch Processing ▼
import { alphatrend_batch_js } from 'vectorta-wasm';
const coeffStart = 1.0, coeffEnd = 2.0, coeffStep = 0.5;
const periodStart = 10, periodEnd = 20, periodStep = 5;
const js = alphatrend_batch_js(open, high, low, close, volume, coeffStart, coeffEnd, coeffStep, periodStart, periodEnd, periodStep, false);
// js = { values: Float64Array, combos: AlphaTrendParams[], rows: 2*combos, cols: N }
const N = js.cols;
// For combo r, values are laid out as [k1_r..., k2_r...] contiguous (block size = 2*N)
const r = 0;
const base = r * 2 * N;
const k1_r = js.values.slice(base, base + N);
const k2_r = js.values.slice(base + N, base + 2*N); CUDA Acceleration
CUDA Support ▼
CUDA support for AlphaTrend is coming soon.
Performance Analysis
AMD Ryzen 9 9950X (CPU) | NVIDIA RTX 4090 (GPU) | Benchmarks: 2026-01-05