TradingView screening workflow

Cup and handle screener: measurable geometry and confirmation delay

A cup and handle screener needs numerical rules for the two rims, cup low, elapsed bars, handle pullback and breakout close. The Pine indicator below applies one fixed-span definition to a finite TradingView watchlist. It returns candidates for chart review, not a judgment that every rounded base is valid. Pineify Market Screener can organize supported technical fields and candidate collections; the cup geometry here runs in TradingView Pine Screener.

Explore Market Screener

Write a definition before scanning

A rounded recovery and a smaller pullback describe the visual idea, but do not specify a unique detector. The original-author descriptions linked below use different pivot, curve and retracement rules. This page supplies an independent fixed-span approximation. Its thresholds are research settings, not an official TradingView pattern definition or a validated trading strategy.

  • The left-rim close must be at least 10% above its close 20 bars earlier. This endpoint test is a coarse prior-rise filter, not proof of a sustained uptrend.
  • All interior cup highs and all handle highs must stay at or below the higher rim. The handle-low rule keeps the pullback within half the cup height, measured down from the right rim.
  • The cup span counts intervals, so 60 intervals contain 61 bars including both rims. The low and dwell tests use only the 59 interior bars. With tied lowest lows, the code uses the more recent one.
  • Daily bars are trading sessions for session-based instruments, not calendar days. Missing history produces blank outputs, not an accepted candidate.
MeasurementDefinition used hereDefault acceptance
Cup durationBar-index distance from left rim to right rim60 daily intervals; configurable from 35 to 130
Cup depth100 × (left rim − lowest interior low) / left rim12% through 33%, inclusive
Rim mismatch100 × abs(right rim − left rim) / left rimNo more than 3%
Bottom location and dwellBottom position within cup; closes in lowest 35% of cup heightBottom in middle 20% to 80%; at least ceil(10% × cup span) low closes
Handle durationBars after the right rim and before the evaluated bar10 daily bars; configurable from 5 to 20
Handle depth and retracement100 × (right rim − handle low) / right rim; same fall / cup heightDepth > 0 and ≤ 12%; retracement ≤ 50%
ConfirmationEvaluated close > max(left rim, right rim)Strict closing break; a touch or wick does not count

A numerical candidate you can audit

Consider a hypothetical left rim of 100 and right rim of 99, separated by 60 daily intervals. The interior low is 80, 30 intervals after the left rim; six interior closes are at or below 87. The left-rim close is 98 versus 88 twenty bars earlier. Assume no interior high exceeds 100. The following ten handle bars have a low of 94 and no high above 100. These assumptions describe the inputs, not observed market performance.

  • A close of 93 with the original handle low of 94 fails the current-candidate check even if the earlier geometry passed.
  • A cup with only five low-region closes fails the default dwell requirement. A single sharp V-bottom therefore cannot pass merely because its depth is acceptable.
  • These calculations classify shapes; they do not calculate a probability, stop-loss, price target or expected return.
TestCalculationResult
Prior rise98 / 88 − 1 = 11.36%Passes the 10% endpoint threshold
Cup depth and rim gap(100 − 80) / 100 = 20%; (100 − 99) / 100 = 1%Both pass
Bottom and dwell30 / 60 = 50%; 80 + 0.35 × 20 = 87; ceil(0.10 × 60) = 6Six low closes meet the dwell minimum
Handle depth(99 − 94) / 99 = 5.05%Below 12%
Handle retracement(99 − 94) / 20 = 25%Below 50%
Closing breakoutPrior close 97; evaluated close 101; rim 100Candidate = 1; Breakout = 1
Exact touch insteadEvaluated close 100Candidate = 1; Breakout = 0
Deep handle insteadHandle low 88: depth 11.11%, retracement 55%Fails despite depth staying below 12%

Scan a finite watchlist with this Pine indicator

Start with a named watchlist, such as 20 exchange-qualified stocks selected for your own research universe. Save this indicator in Pine Editor and add it to favorites. In TradingView Pine Screener, select that watchlist, this indicator and the 1D timeframe. Filter Candidate = 1 for review candidates or Breakout = 1 for the completed closing-break subset. Run the scan again after changing inputs. If Pine Screener is unavailable in your account, apply the same indicator to each daily chart in the saved list.

  • The script evaluates bar [1], the previous daily bar. With defaults, the right rim is high[12], the left rim is high[72], the handle is bars [2] through [11], and the prior-rise comparison reaches close[92]. At least 93 available bars are needed. Every closed bar in that observation window must have nonmissing high, low and close, a positive low, and low ≤ close ≤ high. The current unfinished bar is excluded.
  • Candidate = 1 includes both waiting shapes and completed breakouts. Candidate = 0 means the exact snapshot failed a rule. Blank classification and geometry outputs mean a missing or invalid bar failed the data checks; the timestamp can still be shown.
  • Evaluated bar time is the opening timestamp of the daily bar tested, in Unix milliseconds. Check it against the chart before acting on a stale result.
  • TradingView currently applies a 500-bar calculation window to Pine Screener. This bounded example needs at most 173 bars at its largest duration settings. It scans the chosen list, not an exchange-wide universe.
Pine Script v6. Independent fixed-span example; seven numeric plots and no request calls. Use standard daily candles.pine
//@version=6
indicator("Cup-handle fixed-span scan", overlay = false, max_bars_back = 200)
int cupBars = input.int(60, "Cup span in bars", minval = 35, maxval = 130)
int handleBars = input.int(10, "Handle bars", minval = 5, maxval = 20)
if not timeframe.isdaily or timeframe.multiplier != 1
    runtime.error("Use the 1D interval and standard candles.")
int rightOffset = handleBars + 2
int leftOffset = rightOffset + cupBars
float leftRim = high[leftOffset]
float rightRim = high[rightOffset]
float rim = math.max(leftRim, rightRim)
float bottom = low[rightOffset + 1]
int bottomOffset = rightOffset + 1
float cupHigh = high[rightOffset + 1]
for i = rightOffset + 1 to leftOffset - 1
    if low[i] < bottom
        bottom := low[i]
        bottomOffset := i
    cupHigh := math.max(cupHigh, high[i])
float height = leftRim - bottom
float depthPct = leftRim > 0 ? 100 * height / leftRim : na
float rimGapPct = leftRim > 0 ? 100 * math.abs(rightRim - leftRim) / leftRim : na
float bottomPosition = float(leftOffset - bottomOffset) / cupBars
int lowCloses = 0
for i = rightOffset + 1 to leftOffset - 1
    if close[i] <= bottom + 0.35 * height
        lowCloses += 1
float handleLow = low[2]
float handleHigh = high[2]
for i = 2 to handleBars + 1
    handleLow := math.min(handleLow, low[i])
    handleHigh := math.max(handleHigh, high[i])
float handlePct = rightRim > 0 ? 100 * (rightRim - handleLow) / rightRim : na
float retracePct = height > 0 ? 100 * (rightRim - handleLow) / height : na
bool validWindow = true
for i = 1 to leftOffset + 20
    bool validBar = not na(high[i]) and not na(low[i]) and not na(close[i]) and low[i] > 0 and high[i] >= close[i] and close[i] >= low[i]
    validWindow := validWindow and validBar
bool ready = validWindow and leftRim > 0 and rightRim > 0 and bottom > 0
bool priorRise = close[leftOffset] >= close[leftOffset + 20] * 1.10
bool cupOk = depthPct >= 12 and depthPct <= 33 and rimGapPct <= 3
bool shapeOk = bottomPosition >= 0.20 and bottomPosition <= 0.80 and lowCloses >= math.ceil(0.10 * cupBars) and cupHigh <= rim
bool handleOk = handlePct > 0 and handlePct <= 12 and retracePct <= 50 and handleHigh <= rim
bool geometry = ready and priorRise and cupOk and shapeOk and handleOk
bool candidate = geometry and close[1] >= handleLow
bool breakout = candidate and close[1] > rim and close[2] <= rim
plot(ready ? (candidate ? 1 : 0) : na, "Candidate")
plot(ready ? (breakout ? 1 : 0) : na, "Breakout")
plot(ready ? depthPct : na, "Cup depth percent")
plot(ready ? handlePct : na, "Handle depth percent")
plot(ready ? retracePct : na, "Handle retracement percent")
plot(ready ? rim : na, "Rim")
plot(time[1], "Evaluated bar time")

Understand the confirmation delay and missed patterns

The script always uses the preceding daily bar, so an intraday spike through resistance cannot become a breakout output before that day's close. The result becomes available when the next daily bar starts and the scan runs. For a Friday stock-market close, that can mean the next trading session. This is an intentional one-bar reporting delay, not a promise about data-feed latency.

  • This detector has no future pivot confirmation and does not draw signals back onto old rim bars. All values for a reported snapshot come from already completed bars.
  • It checks exactly one cup span and one handle duration per run. A valid-looking 55-bar cup or an 8-bar handle can be missed with the 60/10 settings. Try a small, predeclared duration grid, such as 40/5, 60/10 and 100/15, and keep results separate.
  • Every new daily bar shifts the anchors. This is a snapshot scan, not a state machine that preserves each discovered base until breakout. Save the matching date, parameters and measured levels; a row disappearing tomorrow does not rewrite yesterday's snapshot.
  • Broader duration searches increase both coverage and the chance of finding coincidental curves. Judge changes on a separate sample rather than tuning until a favored ticker passes.

Reject false matches on the chart

A numerical match does not establish a tradable base. Open every retained symbol on the same exchange, daily interval, session and adjustment settings. Record left-rim date, right-rim date, bottom date, handle dates, tested close and rejection reason. Keep rejected cases alongside accepted ones so later review can measure what the filter misses.

False match or failureWhy the rule can miss the problemManual review
Jagged or double-bottom baseLow-region dwell does not prove smooth curvatureInspect the entire decline and recovery, not just five anchor prices
Downtrend with a short bounceA 20-bar endpoint rise can occur within a longer declineReview preceding trend, nearby supply and the wider chart
Gap or corporate actionHistorical adjustments and gaps can change geometryCheck split adjustments, earnings and issuer announcements
Thin tradingPrice geometry has no spread or depth testReview actual trading activity and executable spread
Weak breakout participationThis example imposes no volume confirmationCompare breakout volume with a stated historical baseline
Immediate failureA closing break can reverse next sessionTrack closes back below the rim and handle low; define risk separately

Use Pineify for candidate organization and source review

In Pineify Market Screener, create a collection of supported symbols on the daily timeframe. Close Price, Relative Volume and Price Breakout State are available technical fields to compare during candidate review. Their built-in definitions are not the fixed cup-and-handle formulas above. Check snapshot timestamps and missing values, then maintain the exact-pattern results in your dated research record.

  • A useful research request is: Find the issuer announcement or filing explaining this price gap on this date; link the primary source and distinguish announced facts from interpretation.
  • Reconcile the exchange-qualified symbol, feed, session and bar date before comparing Pineify snapshots with the Pine output. Different update times can produce different readings without a geometry error.
TaskSupported handoffBoundary
Compare technical contextMarket Screener collection with Close Price, Relative Volume and Price Breakout StateNo verified native cup-depth, cup-duration or handle-retracement field
Apply this exact geometryThe Pine indicator in TradingView Pine Screener or daily chartsPineify Market Screener is not an arbitrary Pine execution service
Check a suspicious gap or eventAsk AI Finance Agent to find dated company news or filings and open the cited sourcePublic research does not establish the chart pattern or repair missing OHLC data
Save the review setKeep supported symbols in a collection and record scan date, settings and reasons separatelyA current collection is not an immutable historical scan archive
Where Pineify fits

Pineify Market Screener

Organize supported symbols and compare available technical fields before reviewing each cup-and-handle candidate on its chart.

Also useful: AI Finance Agent. Research company events behind a candidate's gaps or unusual moves, then verify the dated public sources.

Explore Market Screener

Frequently asked questions

Educational screening example, not investment advice. All numerical cases are hypothetical. Syntax validation does not establish pattern accuracy, live scan reliability or profitability.

Sources and verification

Published by Pineify. Pineify is an independent product and is not affiliated with TradingView. Sources support the technical explanations; examples do not establish trading performance.