Helpers

rolling_mean/std, ta::sma/ema/rsi/atr_bid_ask, signal helpers (cross_above/below, above/below, between, rising/falling), imbalance/cvd/vwap_band.

ta::sma

ta::smafn sma(prices: &[f64], period: usize) -> Vec<f64>

Simple Moving Average. First period-1 entries are NaN.

Example

let sma_20 = ta::sma(&data.mid, 20);

ta::ema

ta::emafn ema(prices: &[f64], period: usize) -> Vec<f64>

Exponential Moving Average. Seeded with the SMA of the first window.

Example

let ema_50 = ta::ema(&data.mid, 50);

ta::rsi

ta::rsifn rsi(prices: &[f64], period: usize) -> Vec<f64>

Relative Strength Index using Wilder smoothing. First period entries are NaN.

Example

let rsi_14 = ta::rsi(&data.mid, 14);

ta::macd

ta::macdfn macd(prices: &[f64], fast: usize, slow: usize, signal: usize) -> (Vec<f64>, Vec<f64>, Vec<f64>)

MACD line, signal line, histogram.

Example

let (macd_line, signal_line, hist) = ta::macd(&data.mid, 12, 26, 9);

ta::bollinger

ta::bollingerfn bollinger(prices: &[f64], period: usize, std_mult: f64) -> (Vec<f64>, Vec<f64>, Vec<f64>)

Bollinger Bands: (upper, middle, lower).

Example

let (upper, middle, lower) = ta::bollinger(&data.mid, 20, 2.0);

ta::stddev

ta::stddevfn stddev(values: &[f64], period: usize) -> Vec<f64>

Rolling standard deviation (population).

Example

let vol = ta::stddev(&data.mid, 30);

ta::atr_bid_ask

ta::atr_bid_askfn atr_bid_ask(bid: &[f64], ask: &[f64], period: usize) -> Vec<f64>

Tick-native ATR equivalent: per-tick range = ask - bid (spread). ATR = SMA(spread, period).

Use this instead of bar-style ATR on TBBO data. The "true range" of a single tick is the spread itself.

Example

let atr = ta::atr_bid_ask(&data.bid, &data.ask, 30);

rolling_mean

rolling_meanfn rolling_mean(values: &[f64], period: usize) -> Vec<f64>

Sliding-window rolling mean with periodic rebuild to bound FP drift.

O(1) per tick via incremental sum (sum += values[i] - values[i - period]), with a full rebuild every period ticks to keep accumulated FP error from flipping signals at edge thresholds.

Example

let baseline = rolling_mean(&data.spread, 200);

rolling_std

rolling_stdfn rolling_std(values: &[f64], period: usize) -> Vec<f64>

Rolling standard deviation (population). Returns NaN for the warm-up window.

Example

let sd = rolling_std(&data.mid, 30);

imbalance (Rust)

imbalance (Rust)fn imbalance(bid: &[f64], ask: &[f64]) -> Vec<f64>

Per-tick bid / (bid + ask + epsilon). Range [0, 1]; 0.5 = balanced.

Example

let imb = imbalance(&data.bid_size, &data.ask_size);

cvd (Rust)

cvd (Rust)fn cvd(delta: &[f64]) -> Vec<f64>

Cumulative volume delta: running sum of a delta series.

Example

let cum = cvd(&data.col_or("delta", &[]));

vwap_band (Rust)

vwap_band (Rust)fn vwap_band(vwap: &[f64], atr: &[f64], mult: f64) -> (Vec<f64>, Vec<f64>)

VWAP envelope: (upper, lower) at mult * ATR.

Example

let (upper, lower) = vwap_band(&data.vwap, &atr, 1.5);

cross_above / cross_below

cross_above / cross_belowfn cross_above(a: &[f64], b: &[f64]) -> Vec<bool>

Element-wise cross detection between two series.

Returns true at index i when a[i-1] < b[i-1] && a[i] >= b[i] (or the symmetric case for cross_below). First element is always false.

Example

let buy = cross_above(&fast_ma, &slow_ma);
let sell = cross_below(&fast_ma, &slow_ma);

above / below / between

Threshold comparisons returning Vec.

above(values, threshold) and below(values, threshold) are strict (> and <); between(values, lo, hi) is inclusive on both ends. NaN entries return false.

Example

let overbought = above(&rsi, 70.0);
let oversold = below(&rsi, 30.0);
let neutral = between(&rsi, 30.0, 70.0);

above_series / below_series

above_series / below_seriesfn above_series(a: &[f64], b: &[f64]) -> Vec<bool>

Element-wise series-vs-series comparison.

Example

let bull = above_series(&data.mid, &ema_200);

rising / falling

rising / fallingfn rising(values: &[f64], length: usize) -> Vec<bool>

True at index i when values[i] > values[i - length] (or < for falling). Warm-up returns false.

Example

let momentum_up = rising(&data.mid, 10);

barssince (Rust)

barssince (Rust)fn barssince(cond: &[bool]) -> Vec<u32>

Ticks since cond[i] was last true. u32::MAX before first occurrence.

Example

let bars_since_signal = barssince(&entry_long);

pad_to_len

pad_to_lenfn pad_to_len(values: &[f64], target_len: usize) -> Vec<f64>

Prepend NaN to a shorter indicator result so it aligns with full tick count.

Some indicator functions return n - period + 1 values starting at index period - 1. pad_to_len pads them back to length n with NaN so signal indexing stays aligned.

Example

let padded = pad_to_len(&truncated_indicator, data.len());