# 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.

<a id="tasma"></a>
## ta::sma

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

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

### Example

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

<a id="taema"></a>
## ta::ema

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

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

### Example

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

<a id="tarsi"></a>
## ta::rsi

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

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

### Example

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

<a id="tamacd"></a>
## ta::macd

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

MACD line, signal line, histogram.

### Example

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

<a id="tabollinger"></a>
## ta::bollinger

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

Bollinger Bands: (upper, middle, lower).

### Example

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

<a id="tastddev"></a>
## ta::stddev

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

Rolling standard deviation (population).

### Example

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

<a id="taatr_bid_ask"></a>
## ta::atr_bid_ask

```rust
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

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

<a id="rolling_mean"></a>
## rolling_mean

```rust
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

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

<a id="rolling_std"></a>
## rolling_std

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

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

### Example

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

<a id="imbalance-rust"></a>
## imbalance (Rust)

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

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

### Example

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

<a id="cvd-rust"></a>
## cvd (Rust)

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

Cumulative volume delta: running sum of a delta series.

### Example

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

<a id="vwap_band-rust"></a>
## vwap_band (Rust)

```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

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

<a id="cross_above-cross_below"></a>
## cross_above / cross_below

```rust
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`](https://quantchartsllc.com/docs/python/py-signals.md#cross_below)). First element is always false.

### Example

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

<a id="above-below-between"></a>
## above / below / between

Threshold comparisons returning Vec<bool>.

[`above(values, threshold)`](https://quantchartsllc.com/docs/python/py-signals.md#above) and [`below(values, threshold)`](https://quantchartsllc.com/docs/python/py-signals.md#below) are strict (`>` and `<`); [`between(values, lo, hi)`](https://quantchartsllc.com/docs/python/py-signals.md#between) is inclusive on both ends. NaN entries return false.

### Example

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

<a id="above_series-below_series"></a>
## above_series / below_series

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

Element-wise series-vs-series comparison.

### Example

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

<a id="rising-falling"></a>
## rising / falling

```rust
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

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

<a id="barssince-rust"></a>
## barssince (Rust)

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

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

### Example

```rust
let bars_since_signal = barssince(&entry_long);
```

<a id="pad_to_len"></a>
## pad_to_len

```rust
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

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