XCREENER Docs
XQLCookbook

Momentum & Trend

Breakouts, crossovers, RSI dips, and MACD momentum.

Each recipe below is a complete core-logic body: drop it under your market/timeframe pragmas and adjust the thresholds to taste. Every query on this page has been parsed and evaluated against the current XQL grammar.

Breakout: New N-Day High

"Closed above the prior 20-bar high": a breakout, not just a new extreme including today's own bar. This uses highest, which excludes the current bar from its window (see Functions). Using max here would make the comparison trivially about whether today's high is also today's close's peer, not a real breakout check.

close > highest(high, 20)

Crossed in the Last Few Days

A raw crossover(...) call can't be offset-indexed directly: crossover(a, b)[-1] is invalid, since crossovers carry no offset field of their own. Bind the crossover to a let first, then or-chain the offsets you want to check:

let x = crossover(ema(50), ema(200))
x or x[-1] or x[-2]

This matches if the golden cross happened on the current bar, one bar back, or two bars back.

RSI Oversold Within an Uptrend

A bare rsi(14) < 30 catches oversold conditions in any trend, including a strong downtrend where "oversold" can keep getting more oversold. Gating it with a longer moving average filters for "buy the dip," not "catch the falling knife":

rsi(14) < 30 and close > sma(200)

Matches only when the instrument is both short-term oversold and still above its own long-term trend.

MACD Histogram Growing

"MACD histogram growing" doesn't need arithmetic: just an offset comparison against the histogram's own prior value:

let h = macd_hist(12, 26, 9)
h > h[-1]

N% above its moving average

The same arithmetic shape as the Bollinger width recipe generalizes to "price N% above its moving average", e.g. (close - sma(50)) / sma(50) > 0.05 for "5% above its 50-period average."

On this page