# Signal Helpers

Crossover detection, threshold checks, streak counting, and order-flow primitives (cvd, imbalance, vwap_band).

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

```python
cross_above(series1, series2)
```

Detect where series1 crosses above series2.

Returns a boolean Series that is `True` on bars where `series1` crosses above `series2`. A crossover occurs when `series1` was at or below `series2` on the previous bar and is now above it.

### Parameters

- `series1` (`Series`, default `required`): The series crossing up
- `series2` (`Series`, default `required`): The reference level (series or number)

### Returns

numpy boolean array

### Example

```python
from quant_charts import cross_above, close
fast_ma = close.rolling(10).mean()
slow_ma = close.rolling(20).mean()
buy_signal = cross_above(fast_ma, slow_ma)
```

### Notes

- Equivalent to: `(s1 > s2) & (s1.shift(1) <= s2.shift(1))`

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

```python
cross_below(series1, series2)
```

Detect where series1 crosses below series2.

Returns a boolean Series that is `True` on bars where `series1` crosses below `series2`.

### Parameters

- `series1` (`Series`, default `required`): The series crossing down
- `series2` (`Series`, default `required`): The reference level (series or number)

### Returns

numpy boolean array

### Example

```python
sell_signal = cross_below(fast_ma, slow_ma)
```

### Notes

- Equivalent to: `(s1 < s2) & (s1.shift(1) >= s2.shift(1))`

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

```python
above(series, value)
```

True where series is strictly above value.

Element-wise comparison. Works with both numpy arrays and pandas Series. `value` can be a number or another series.

### Parameters

- `series` (`array-like`, default `required`): Input data
- `value` (`number | array`, default `required`): Threshold value or series

### Returns

numpy boolean array

### Example

```python
from quant_charts import above, ta, close
rsi = ta.rsi(close, 14)
is_overbought = above(rsi, 70)
```

### Notes

- Strict comparison: `series > value`

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

```python
below(series, value)
```

True where series is strictly below value.

### Parameters

- `series` (`array-like`, default `required`): Input data
- `value` (`number | array`, default `required`): Threshold value or series

### Returns

numpy boolean array

### Example

```python
is_oversold = below(rsi, 30)
```

### Notes

- Strict comparison: `series < value`

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

```python
between(series, lower, upper)
```

True where lower <= series <= upper (inclusive).

### Parameters

- `series` (`array-like`, default `required`): Input data
- `lower` (`number`, default `required`): Lower bound (inclusive)
- `upper` (`number`, default `required`): Upper bound (inclusive)

### Returns

numpy boolean array

### Example

```python
is_neutral = between(rsi, 30, 70)
```

### Notes

- Inclusive on both ends: `lower <= series <= upper`

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

```python
rising(series, length)
```

True if series has been rising for N consecutive bars.

### Parameters

- `series` (`array-like`, default `required`): Input data
- `length` (`int`, default `required`): Number of consecutive rising bars required

### Returns

numpy boolean array

### Example

```python
from quant_charts import rising, close
uptrend = rising(close, 3)  # 3 consecutive higher closes
```

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

```python
falling(series, length)
```

True if series has been falling for N consecutive bars.

### Parameters

- `series` (`array-like`, default `required`): Input data
- `length` (`int`, default `required`): Number of consecutive falling bars required

### Returns

numpy boolean array

### Example

```python
downtrend = falling(close, 3)
```

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

```python
barssince(condition)
```

Count bars since condition was last True.

Returns an array where each element is the number of bars since `condition` was last `True`. Values before the first `True` are `NaN`.

### Parameters

- `condition` (`bool array`, default `required`): Boolean condition array

### Returns

numpy float array (NaN before first occurrence)

### Example

```python
from quant_charts import barssince, cross_above
bars_since_buy = barssince(cross_above(fast, slow))
```

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

```python
valuewhen(condition, source, occurrence?)
```

Get the value of source when condition was last True.

Returns the value of `source` at the most recent bar where `condition` was `True`. `occurrence=0` is the most recent, `occurrence=1` is the one before that.

### Parameters

- `condition` (`bool array`, default `required`): Boolean condition array
- `source` (`array-like`, default `required`): Values to sample from
- `occurrence` (`int`, default `0`): 0 = most recent, 1 = previous, etc.

### Returns

numpy float array

### Example

```python
from quant_charts import valuewhen, cross_above, close
entry_price = valuewhen(cross_above(fast, slow), close, 0)
```

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

```python
imbalance(bid_size, ask_size)
```

Order-book imbalance: bid / (bid + ask).

Returns a value in [0, 1] where 0.5 is balanced, > 0.5 is bid-heavy (buy pressure), < 0.5 is ask-heavy. Safe on zero volume.

### Parameters

- `bid_size` (`array-like`, default `required`): Bid-side size series
- `ask_size` (`array-like`, default `required`): Ask-side size series

### Returns

numpy array of floats in [0, 1]

### Example

```python
from quant_charts import imbalance, bid_vol, ask_vol
imb = imbalance(bid_vol, ask_vol)
buy_pressure = imb > 0.6
```

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

```python
cvd(delta)
```

Cumulative volume delta: running sum of signed volume.

Trends up when buyers lift the offer, down when sellers hit the bid.

### Parameters

- [`delta`](https://quantchartsllc.com/docs/python/py-data.md#delta) (`array-like`, default `required`): Per-bar signed delta (e.g. `delta` series)

### Returns

numpy array of cumulative delta

### Example

```python
from quant_charts import cvd, delta
cumdelta = cvd(delta)
```

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

```python
vwap_band(vwap, atr, mult?)
```

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

### Parameters

- [`vwap`](https://quantchartsllc.com/docs/python/py-data.md#vwap) (`array-like`, default `required`): VWAP series
- `atr` (`array-like`, default `required`): ATR series (same length as vwap)
- `mult` (`float`, default `1.0`): Band width as multiple of ATR

### Returns

(upper, lower) tuple of numpy arrays

### Example

```python
from quant_charts import vwap_band, vwap, ta, high, low, close
atr = ta.atr(high, low, close, 14)
upper, lower = vwap_band(vwap, atr, mult=1.5)
```
