How to find uptrend pullbacks with ChatGPT or Claude
Reviewed
Ask it
Using Monk.trade, find stocks in uptrends that pulled back to their 20-day average on light volume in the last completed session and closed back above it.
Opens with the question filled in; nothing is sent until you press send. In ChatGPT, you can also type @ and choose Monk.trade. Not connected? Help
Precise version: the same rule every time
Using Monk.trade, check the last completed daily session for common stocks averaging at least $20M in daily trading value. Require a 20-day EMA at least 2% above the 50-day SMA, with both averages higher than 5 sessions earlier. Find stocks whose low reached or fell below the EMA and whose close held at or above it, on volume below 80% of the prior 20-day average.
What you get back
A starting list for research. It does not recommend any trade.
Example · run · data to
| Symbol | Close | 20-day avg | Vol vs usual | Days above (of 30) |
|---|---|---|---|---|
| NTSK | $22.77 | $22.23 | 0.72× | 28 |
| PD | $17.00 | $16.73 | 0.77× | 28 |
| WS | $40.48 | $40.14 | 0.71× | 28 |
| AI | $11.96 | $11.77 | 0.67× | 26 |
| MANE | $136.51 | $130.69 | 0.67× | 24 |
Seven stocks matched at the Nov 4 close; these five closed above their average most often. The next session WS fell to $35.90, well below its average.
US stocks, ETFs and futures. The free plan runs 20 queries a day on daily bars; Pro adds intraday.
Then ask
Paste these into the same chat, after the first answer, so your AI knows which results you mean.
Chart the top three with their 20-day and 50-day averages.
Which of these reported earnings in the past month?
Any insider buying in these over the past three months?
Keep only the ones within 10% of their 52-week high.
What counts
A pullback is a brief dip during an advance. This scan looks for a low that reached a rising 20-day average, followed by a close back above it on lighter volume. The 20-day average must also sit above a rising 50-day average.
The rule Monk.trade uses: common stocks averaging at least $20M traded a day, checked on the last completed session. The 20-day EMA must be at least 2% above the 50-day SMA, and both must be higher than five sessions earlier. The low must reach or fall below the EMA, the close must hold at or above it, and volume must stay under 80% of the preceding 20-session average.
New to these terms?
- Moving average
- The average closing price over the last so many days. When it is rising, the stock is in an uptrend.
- EMA and SMA
- Two kinds of moving average. An EMA (exponential) counts recent days more, so it turns sooner; an SMA (simple) counts every day equally.
- Pullback
- A short dip during an uptrend, before the price either resumes rising or keeps falling.
- Volume
- How many shares traded in a day. A dip on lighter volume than usual suggests few sellers were pushing the price down.
- Completed session
- A trading day that has closed, so its price range and volume are final.
Variations
Pullbacks to the 50-day average
“Using Monk.trade, check the last completed daily session for common stocks averaging at least $20M traded a day. Require a 50-day SMA at least 2% above the 200-day SMA and higher than 10 sessions earlier. Find stocks whose low reached the 50-day SMA and whose close held at or above it, on volume below 80% of the prior 20-day average.”
MonkQL
from stocks let s50 = sma(close, 50) let s200 = sma(close, 200) include type == "common" and sma(close * volume, 20)[2] >= 20000000 where s50[1] >= 1.02 * s200[1] and s50[1] > s50[11] and low[1] <= s50[1] and close[1] >= s50[1] and volume[1] < 0.8 * sma(volume, 20)[2] show close[1] as prior_close, s50[1] as sma_50, volume[1] / sma(volume, 20)[2] as vol_ratio sort close[1] / s200[1] desc take 5Pullbacks within 10% of a 52-week high
“Using Monk.trade, find completed-session 20-day EMA pullbacks with a close within 10% of the 52-week high. Keep common stocks, the $20M average daily trading value floor and the 2% gap between the EMA and SMA.”
MonkQL
from stocks let e20 = ema(close, 20) let s50 = sma(close, 50) include type == "common" and sma(close * volume, 20)[2] >= 20000000 where e20[1] >= 1.02 * s50[1] and e20[1] > e20[6] and s50[1] > s50[6] and low[1] <= e20[1] and close[1] >= e20[1] and volume[1] < 0.8 * sma(volume, 20)[2] and close[1] >= 0.9 * highest(high, 252)[1] show close[1] as prior_close, e20[1] as ema_20, volume[1] / sma(volume, 20)[2] as vol_ratio, count(close > e20, 30)[1] as days_above sort count(close > e20, 30)[1] desc take 5
Check before you act
- Nothing on this page is a signal to buy or sell. Prices can keep moving against you, and you can lose money.
- The query reads the bar before the newest, which is the last completed session while the market is open. Before the open or after the close the newest bar is already complete, so this example, run before the Nov 6 open, read Nov 4. Ask your AI to check the newest session instead.
- A moving average may fail to hold as support. A change in momentum or news can push a stock below its 20-day or 50-day average.
- Stocks with fewer than 56 sessions lack the history needed to compare the completed 50-day average with its value five bars earlier. The scan reports them as undecided.
- Earnings releases, ex-dividend dates and merger agreements can bring a price to its moving average for reasons unrelated to a routine pullback.
The query
The MonkQL your AI writes
from stocksScan active US stocks on regular daily bars.
let e20 = ema(close, 20)Name the 20-session exponential moving average of the close.
let s50 = sma(close, 50)Name the 50-session simple moving average of the close.
include type == "common" and sma(close * volume, 20)[2] >= 20000000Keep common stocks with at least $20M in average daily trading value over the 20 sessions before the completed bar.
where e20[1] >= 1.02 * s50[1] and e20[1] > e20[6] and s50[1] > s50[6] and low[1] <= e20[1] and close[1] >= e20[1] and volume[1] < 0.8 * sma(volume, 20)[2]Use the last completed bar, [1]. Require the EMA to be at least 2% above the SMA, with both higher than five sessions earlier. The low must reach the EMA and the close must hold at or above it, on volume below 80% of the preceding average.
show close[1] as prior_close, e20[1] as ema_20, volume[1] / sma(volume, 20)[2] as vol_ratio, count(close > e20, 30)[1] as days_aboveShow the completed close, 20-day EMA and volume relative to its average. Count the closes above the EMA over 30 sessions.
sort count(close > e20, 30)[1] descRank by the number of closes above the EMA over 30 sessions.
take 5Return up to five stocks.
Ask your AI to show the query it ran. The example came from run 01a1b13a-3072-7330-a05f-6e362ca2f77e.
Research only. Not investment advice. Read the risk notice