# Operators & conditions

> How values compare: stative comparisons, cross events, and the expression form for advanced logic.

Source: https://docs.texttoquant.com/reference/operators

---

Operators are how a query compares one value to another: an indicator to a number, a series to
another series, or a price to a level. Crosses compare against the previous bar; percentile ranks
compare against trailing history.

## Comparison & event operators

| Operator | Meaning |
| --- | --- |
| above / below | Stative compare vs a value or another series |
| at or above / at or below | Inclusive compare (`>=` / `<=`) |
| equals / not equal to | Exact match / mismatch, e.g. a flag `== 1` |
| between / outside | Inside or outside a range, e.g. `RSI between 40 and 60` |
| crosses above / below | Event; compares against the previous bar |
| rising / falling | Series turning up / down |
| reaches | Price attains a dynamic level (TP / SL) |
| retests | Returns to a level after breaking through it |
| touches | Hits a band or level |
| deviates above / below | Moves X% or X ATR from a reference |
| divergence bull / bear | Price pivot vs an oscillator pivot: RSI, MACD, OBV, volume, CCI, MFI, ROC, Williams %R or stochastic |
| stays idle | Level unchanged for N bars |

<Callout variant="info" title="Crosses use the previous bar">
  A "cross above" is an *event*: it fires only on the bar where the series moves from below to above.
  A "stays above" is a *state*: it's true on every bar where the condition holds.
</Callout>

## Advanced operators

Beyond the basics, the parser understands a range of specialised comparisons.

| Operator | Example |
| --- | --- |
| within X% of | `price within 0.5% of the VWAP`, proximity to a level or series |
| for N bars | `RSI stays above 50 for 3 consecutive bars`, a state must persist |
| present / absent | `a buy signal prints`, `no sell signal`, a marker fires, or doesn't |
| inside / outside zone | `price is inside a bullish order block`, `price leaves the fair-value gap` |
| zone formed | `a new fair-value gap forms`, a supply/demand zone just appeared |
| expansion bar | `the bar range expands beyond 1.5× its recent average` |
| gaps up / down X% | `price opens 2% above the previous close` |
| N of the last M | `3 of the last 5 closes are above the VWAP`, `a majority of the last 10 candles are green` |
| the Nth time | `the 2nd time RSI crosses above 30`, pick a specific occurrence |
| within the last N bars | `RSI crossed above 30 within the last 10 bars`, optionally `at least K times` |

<Callout variant="info" title="Smart-money zones">
  The zone operators (`inside`/`outside`/`formed`) work on structure sources: fair-value gaps, order
  blocks, breakers, liquidity sweeps, and read a zone's freshness (fresh, tested, mitigated), so
  "price taps an *unmitigated* order block" is expressible. See the structure indicators in the
  [indicator library](/docs/reference/indicators).
</Callout>

## Expression form

For comparisons the flat operators can't express, rolling windows, N bars ago, multiples, or any
indicator as an operand:

| Building block | Example |
| --- | --- |
| Rolling window | `the 20-bar highest high`, `20-bar mean volume` |
| N bars ago | `RSI vs its value 5 bars ago` |
| Multiple | `volume above 2× its 20-bar average` |
| Aggregation | `highest`, `lowest`, `mean`, `sum`, `std` or `median` over a rolling window |
| Value when | `the RSI value the last time price crossed the 200 EMA` (value-when) |
| Indicator operand | `EMA of RSI`, `MACD histogram vs 0` |

## Combining conditions

Join conditions with `AND` (every one true on the same bar) or `OR` (any one true). To require that
one condition happens *after* another, chain them with `then`. That makes a **sequential** entry: the
steps must fire in order, not all at once.

```text
Buy when RSI crosses above 50 AND price breaks the swing high
Buy when the 12 EMA crosses above the 21 EMA, then price retests the 21 EMA
```

| Logic | Meaning |
| --- | --- |
| `AND` | every condition is true on the **same** bar |
| `OR` | **any** condition is true |
| `then` (sequential) | conditions fire **in order**, each within a window of the previous step |

### Sequential timeout

A sequential entry puts a deadline on each step: the next condition must occur within a set number of
bars of the one before it, or the sequence resets and starts watching for step one again. The default
window is **50 bars**. Set your own with `within N bars`.

```text
Buy when the 12 EMA crosses above the 21 EMA, then price retests the 21 EMA within 20 bars
```

<Callout variant="tip" title="Order matters">
  In a sequential entry the conditions are matched strictly in the order you write them. Reordering
  the clauses changes the strategy; `AND` does not.
</Callout>

## Beyond a plain comparison

A lot of ideas aren't shaped like "value vs number": where price sits in its 52-week range, how many
bars since a signal, whether a state held for five bars, relative volume, a move measured in ATR.
Those are documented as their own reference, see
[phrasing families](/docs/reference/phrasings) for the exact wording and the maths behind each one.

See [entry & exit](/docs/reference/entry-exit) for how conditions, stops and sizing come
together.
