# Technical Analysis

Vectorized ta.* namespace: moving averages, RSI, MACD, Bollinger, ATR, and friends.

<a id="ta-sma"></a>
## ta.sma

```python
ta.sma(source, period)
```

Simple Moving Average.

Calculates the arithmetic mean of `source` over a rolling window of `period` bars. Uses Numba JIT compilation for datasets > 10,000 values.

### Parameters

- `source` (`array-like`, default `required`): Price data (pandas Series or numpy array)
- `period` (`int`, default `required`): Number of bars in the lookback window

### Returns

numpy array

### Example

```python
from quant_charts import ta, close
sma = ta.sma(close, 20)
# Smooth an existing result (numpy -> numpy)
smoothed = ta.sma(sma, 5)
```

### Notes

- Returns a numpy array, NOT a pandas Series.
- Use `ta.sma()` to smooth other `ta.*` results instead of `.rolling().mean()`.

<a id="ta-ema"></a>
## ta.ema

```python
ta.ema(source, period)
```

Exponential Moving Average.

Gives more weight to recent values. Faster to react than SMA.

### Parameters

- `source` (`array-like`, default `required`): Price data
- `period` (`int`, default `required`): Lookback period (span)

### Returns

numpy array

### Example

```python
ema = ta.ema(close, 12)
```

<a id="ta-wma"></a>
## ta.wma

```python
ta.wma(source, period)
```

Weighted Moving Average.

Linearly weights recent values more heavily than older ones.

### Parameters

- `source` (`array-like`, default `required`): Price data
- `period` (`int`, default `required`): Lookback period

### Returns

numpy array

### Example

```python
wma = ta.wma(close, 20)
```

<a id="ta-rsi"></a>
## ta.rsi

```python
ta.rsi(source, period)
```

Relative Strength Index (0-100).

Momentum oscillator that measures the speed and magnitude of price changes. Values above 70 indicate overbought, below 30 oversold.

### Parameters

- `source` (`array-like`, default `required`): Price data
- `period` (`int`, default `14`): Lookback period

### Returns

numpy array

### Example

```python
rsi = ta.rsi(close, 14)
# Smooth RSI with SMA (correct numpy approach)
smooth_rsi = ta.sma(rsi, 5)
```

### Notes

- The result is a numpy array. Do NOT call `.rolling()` on it.

<a id="ta-macd"></a>
## ta.macd

```python
ta.macd(source, fast?, slow?, signal?)
```

Moving Average Convergence Divergence.

Returns a tuple of three numpy arrays: MACD line, signal line, and histogram. Use tuple unpacking.

### Parameters

- `source` (`array-like`, default `required`): Price data
- `fast` (`int`, default `12`): Fast EMA period
- `slow` (`int`, default `26`): Slow EMA period
- `signal` (`int`, default `9`): Signal line EMA period

### Returns

tuple: (macd_line, signal_line, histogram), all numpy arrays

### Example

```python
macd_line, signal_line, histogram = ta.macd(close)
buy = cross_above(macd_line, signal_line)
```

<a id="ta-stochastic"></a>
## ta.stochastic

```python
ta.stochastic(high, low, close, k_period?, d_period?)
```

Stochastic Oscillator (%K and %D).

### Parameters

- [`high`](https://quantchartsllc.com/docs/python/py-data.md#high) (`array-like`, default `required`): High prices
- [`low`](https://quantchartsllc.com/docs/python/py-data.md#low) (`array-like`, default `required`): Low prices
- [`close`](https://quantchartsllc.com/docs/python/py-data.md#close) (`array-like`, default `required`): Close prices
- `k_period` (`int`, default `14`): %K lookback period
- `d_period` (`int`, default `3`): %D smoothing period

### Returns

tuple: (k, d), both numpy arrays

### Example

```python
k, d = ta.stochastic(high, low, close, 14, 3)
buy = cross_above(k, d) & below(k, 20)
```

<a id="ta-bollinger_bands"></a>
## ta.bollinger_bands

```python
ta.bollinger_bands(source, period?, std?)
```

Bollinger Bands (upper, middle, lower).

### Parameters

- `source` (`array-like`, default `required`): Price data
- `period` (`int`, default `20`): SMA period
- `std` (`float`, default `2.0`): Standard deviation multiplier

### Returns

tuple: (upper, middle, lower), all numpy arrays

### Example

```python
upper, mid, lower = ta.bollinger_bands(close, 20, 2.0)
plot(upper, "Upper BB")
plot(lower, "Lower BB")
fill("Upper BB", "Lower BB", color="#2962FF", opacity=10)
```

<a id="ta-atr"></a>
## ta.atr

```python
ta.atr(high, low, close, period?)
```

Average True Range, a volatility measure.

### Parameters

- `high` (`array-like`, default `required`): High prices
- `low` (`array-like`, default `required`): Low prices
- `close` (`array-like`, default `required`): Close prices
- `period` (`int`, default `14`): Lookback period

### Returns

numpy array

### Example

```python
atr = ta.atr(high, low, close, 14)
avg_atr = ta.sma(atr, 50)
high_vol = atr > avg_atr
```

<a id="ta-stddev"></a>
## ta.stddev

```python
ta.stddev(source, period)
```

Rolling standard deviation.

### Parameters

- `source` (`array-like`, default `required`): Input data
- `period` (`int`, default `required`): Lookback window

### Returns

numpy array

### Example

```python
vol = ta.stddev(close, 20)
```

<a id="ta-highest"></a>
## ta.highest

```python
ta.highest(source, period)
```

Rolling maximum over a lookback window.

### Parameters

- `source` (`array-like`, default `required`): Input data
- `period` (`int`, default `required`): Lookback window

### Returns

numpy array

### Example

```python
resistance = ta.highest(high, 20)
```

<a id="ta-lowest"></a>
## ta.lowest

```python
ta.lowest(source, period)
```

Rolling minimum over a lookback window.

### Parameters

- `source` (`array-like`, default `required`): Input data
- `period` (`int`, default `required`): Lookback window

### Returns

numpy array

### Example

```python
support = ta.lowest(low, 20)
```

<a id="ta-change"></a>
## ta.change

```python
ta.change(source, length?)
```

Difference between current and N bars ago.

Equivalent to pandas `.diff(length)` but works on numpy arrays.

### Parameters

- `source` (`array-like`, default `required`): Input data
- `length` (`int`, default `1`): Lookback distance

### Returns

numpy array

### Example

```python
momentum = ta.change(close, 10)
```

### Notes

- Use this instead of `.diff()` on numpy arrays from `ta.*` results.

<a id="ta-roc"></a>
## ta.roc

```python
ta.roc(source, length?)
```

Rate of change in percent.

Calculates `100 * (current - previous) / previous`. Equivalent to pandas `.pct_change() * 100`.

### Parameters

- `source` (`array-like`, default `required`): Input data
- `length` (`int`, default `1`): Lookback distance

### Returns

numpy array (percentage values)

### Example

```python
pct_change = ta.roc(close, 5)
```

### Notes

- Returns percentage (e.g. 2.5 not 0.025). Divide by 100 for decimal.
