<!-- Generated from TradeReady.io docs. Visit https://tradeready.io/docs for the full experience. -->

---
title: Built-in Indicators
description: 7 technical indicators available for strategy entry and exit conditions
---

The platform computes 7 technical indicators using pure numpy — no TA-Lib dependency. Indicators are recomputed on every candle close for every pair in your strategy's `pairs` list, using the candle interval set in `timeframe`.

Each indicator produces one or more output values that map directly to condition keys in `entry_conditions` and `exit_conditions`.

> **Info:**
> All indicators require a minimum number of candles before they produce valid values. Strategies will not generate signals until enough history is available.

---

## RSI — Relative Strength Index

**Measures:** Momentum — how overbought or oversold an asset is.

**Period:** 14 candles. **Minimum data:** 15 candles.

RSI oscillates between 0 and 100. Values below 30 indicate oversold conditions (potential bounce). Values above 70 indicate overbought conditions (potential reversal).

| Output key | Description |
|------------|-------------|
| `rsi_14` | RSI value, 0–100 |

**Entry condition keys:**

| Key | Type | Example | When true |
|-----|------|---------|-----------|
| `rsi_below` | `float` | `30` | RSI(14) is below this value — oversold signal |
| `rsi_above` | `float` | `50` | RSI(14) is above this value — momentum confirmation |

**Exit condition keys:**

| Key | Type | Example | When true |
|-----|------|---------|-----------|
| `rsi_above` | `float` | `70` | RSI rose above threshold — overbought, exit long |
| `rsi_below` | `float` | `35` | RSI dropped below threshold — momentum fading |

**Typical usage:**

```json
{
  "entry_conditions": { "rsi_below": 30 },
  "exit_conditions": { "rsi_above": 70 }
}
```

---

## MACD — Moving Average Convergence Divergence

**Measures:** Trend direction and momentum changes via moving average crossovers.

**Periods:** Fast EMA 12, slow EMA 26, signal EMA 9. **Minimum data:** 26 candles.

MACD produces three values: the MACD line (fast EMA minus slow EMA), the signal line (EMA of MACD), and the histogram (MACD minus signal). A bullish crossover happens when the MACD line crosses above the signal line.

| Output key | Description |
|------------|-------------|
| `macd_line` | MACD line value |
| `macd_signal` | Signal line value |
| `macd_hist` | Histogram (MACD - signal) |

**Condition keys:**

| Key | Type | Example | When true |
|-----|------|---------|-----------|
| `macd_cross_above` (entry) | `bool` | `true` | MACD line just crossed above signal — bullish |
| `macd_cross_below` (entry/exit) | `bool` | `true` | MACD line just crossed below signal — bearish |

**Typical usage:**

```json
{
  "entry_conditions": { "macd_cross_above": true, "adx_above": 25 },
  "exit_conditions": { "macd_cross_below": true }
}
```

> **Info:**
> `macd_cross_above` and `macd_cross_below` detect the crossover event — they are `true` only on the candle where the cross occurs, not on every subsequent candle.

---

## SMA — Simple Moving Average

**Measures:** Trend direction by averaging the closing price over N candles.

**Periods:** 20 and 50. **Minimum data:** Equal to the period.

SMA smooths out price noise. When price is above a long-period SMA, the asset is in an uptrend. When price crosses above a short SMA from below, it signals a potential trend entry.

| Output key | Description |
|------------|-------------|
| `sma_20` | 20-period simple moving average |
| `sma_50` | 50-period simple moving average |

**Entry condition keys:**

| Key | Type | Example | When true |
|-----|------|---------|-----------|
| `price_above_sma` | `int` | `50` | Price is above the SMA of this period — uptrend filter |
| `price_below_sma` | `int` | `20` | Price is below the SMA of this period — reversion setup |

**Typical usage:**

```json
{
  "entry_conditions": { "price_above_sma": 50, "macd_cross_above": true }
}
```

---

## EMA — Exponential Moving Average

**Measures:** Trend direction like SMA but with more weight on recent prices, so it reacts faster.

**Periods:** 12 and 26. **Minimum data:** Equal to the period.

| Output key | Description |
|------------|-------------|
| `ema_12` | 12-period exponential moving average |
| `ema_26` | 26-period exponential moving average |

**Entry condition keys:**

| Key | Type | Example | When true |
|-----|------|---------|-----------|
| `price_above_ema` | `int` | `12` | Price is above the EMA of this period |
| `price_below_ema` | `int` | `26` | Price is below the EMA of this period |

**Typical usage — fast-reacting trend filter:**

```json
{
  "entry_conditions": { "price_above_ema": 12, "volume_above_ma": 1.5 }
}
```

---

## Bollinger Bands

**Measures:** Volatility and price extremes relative to a moving average.

**Period:** 20, standard deviation multiplier: 2. **Minimum data:** 20 candles.

Bollinger Bands produce three lines: the middle band (SMA-20), an upper band (SMA + 2 std), and a lower band (SMA - 2 std). When price touches the lower band, it may be oversold. When price breaks above the upper band, it may signal a breakout.

| Output key | Description |
|------------|-------------|
| `bb_upper` | Upper band (SMA + 2 std) |
| `bb_middle` | Middle band (SMA-20) |
| `bb_lower` | Lower band (SMA - 2 std) |

**Entry condition keys:**

| Key | Type | Example | When true |
|-----|------|---------|-----------|
| `bb_below_lower` | `bool` | `true` | Price is below the lower band — mean reversion setup |
| `bb_above_upper` | `bool` | `true` | Price is above the upper band — breakout signal |

**Typical usage — mean reversion:**

```json
{
  "entry_conditions": { "bb_below_lower": true, "rsi_below": 40 },
  "exit_conditions": { "rsi_above": 60 }
}
```

---

## ADX — Average Directional Index

**Measures:** Trend strength (not direction — only how strong the trend is, regardless of which way it's going).

**Period:** 14. **Minimum data:** 15 candles.

ADX ranges from 0 to 100. Values above 25 indicate a strong trend is present. Values below 20 suggest a ranging, choppy market where trend-following strategies tend to underperform.

| Output key | Description |
|------------|-------------|
| `adx` | ADX value, 0–100 |

**Entry condition key:**

| Key | Type | Example | When true |
|-----|------|---------|-----------|
| `adx_above` | `float` | `25` | ADX is above this threshold — trend is strong enough to trade |

**Typical usage — trend filter (prevents entries in choppy markets):**

```json
{
  "entry_conditions": {
    "macd_cross_above": true,
    "adx_above": 25
  }
}
```

> **Warning:**
> The recommendation engine flags `adx_above` thresholds above 30 as potentially too restrictive (missing valid entries) and below 15 as too permissive (entering in choppy markets). The 20–25 range is the sweet spot for most strategies.

---

## ATR — Average True Range

**Measures:** Volatility — how much an asset moves per candle on average.

**Period:** 14. **Minimum data:** 15 candles.

ATR measures the average range of price movement across 14 candles. It is not used directly in entry/exit condition keys, but it appears in the observation space for Gymnasium environments where your model can use it as a volatility signal.

| Output key | Description |
|------------|-------------|
| `atr` | Average true range in price units |

ATR is most useful for dynamic position sizing — size smaller when ATR is high (volatile), larger when ATR is low (calm) — which you can implement in a Gymnasium agent or a custom strategy executor.

---

## Volume Moving Average

**Measures:** Whether current trading volume is higher than the recent average — confirms that a price move has buying/selling conviction behind it.

**Period:** 20. **Minimum data:** 20 candles.

| Output key | Description |
|------------|-------------|
| `volume_ma_20` | 20-period simple moving average of volume |

**Entry condition key:**

| Key | Type | Example | When true |
|-----|------|---------|-----------|
| `volume_above_ma` | `float` | `1.5` | Current volume > 1.5x the 20-period average |

**Typical usage — confirm breakouts with volume:**

```json
{
  "entry_conditions": {
    "bb_above_upper": true,
    "volume_above_ma": 2.0,
    "adx_above": 25
  }
}
```

---

## Complete Condition Reference

### All Entry Conditions (AND logic)

| Key | Type | Description |
|-----|------|-------------|
| `rsi_below` | `float` | RSI(14) below value — oversold |
| `rsi_above` | `float` | RSI(14) above value — momentum |
| `macd_cross_above` | `bool` | MACD crossed above signal this candle |
| `macd_cross_below` | `bool` | MACD crossed below signal this candle |
| `price_above_sma` | `int` | Price above SMA of this period |
| `price_below_sma` | `int` | Price below SMA of this period |
| `price_above_ema` | `int` | Price above EMA of this period |
| `price_below_ema` | `int` | Price below EMA of this period |
| `bb_below_lower` | `bool` | Price below lower Bollinger Band |
| `bb_above_upper` | `bool` | Price above upper Bollinger Band |
| `adx_above` | `float` | ADX(14) above threshold |
| `volume_above_ma` | `float` | Volume above N times the 20-period volume MA |

### All Exit Conditions (OR logic, priority order)

| Key | Type | Priority | Description |
|-----|------|----------|-------------|
| `stop_loss_pct` | `float` | 1 (highest) | Exit when loss from entry >= this % |
| `take_profit_pct` | `float` | 2 | Exit when gain from entry >= this % |
| `trailing_stop_pct` | `float` | 3 | Exit when price drops this % from peak since entry |
| `max_hold_candles` | `int` | 4 | Force exit after N candles (prevents stuck positions) |
| `rsi_above` | `float` | 5 | Exit when RSI rises above value |
| `rsi_below` | `float` | 5 | Exit when RSI falls below value |
| `macd_cross_below` | `bool` | 5 | Exit when MACD turns bearish |

---

## Common Strategy Patterns

| Style | Entry | Exit |
|-------|-------|------|
| RSI Oversold Bounce | `{"rsi_below": 30, "adx_above": 20}` | `{"take_profit_pct": 5, "stop_loss_pct": 2}` |
| MACD Momentum | `{"macd_cross_above": true, "volume_above_ma": 1.2}` | `{"macd_cross_below": true, "stop_loss_pct": 3}` |
| Bollinger Mean Reversion | `{"bb_below_lower": true, "rsi_below": 40}` | `{"rsi_above": 60, "max_hold_candles": 24}` |
| Trend Following | `{"price_above_sma": 50, "macd_cross_above": true, "adx_above": 25}` | `{"trailing_stop_pct": 2, "stop_loss_pct": 4}` |
| Volume Breakout | `{"price_above_ema": 20, "volume_above_ma": 2.0, "adx_above": 30}` | `{"take_profit_pct": 8, "stop_loss_pct": 2}` |

---

## Next Steps

- [Strategy Testing](/docs/strategies/testing) — run your strategy against historical episodes
- [Deploying Strategies](/docs/strategies/deployment) — go live after validation
