OPEN-SOURCE SCRIPT
CAN SLIM Checker

WHAT THIS IS
A single diagnostic table that scores the chart's symbol against William O'Neil's CAN SLIM criteria - 17 pass/fail checks plus 4 informational rows - and tells you plainly which ones it clears, which it fails, and which cannot be evaluated because the data does not exist.
Every row shows three things: the actual value, the threshold it has to clear, and the verdict. The threshold string is generated from the same input the pass/fail test reads, so retuning a setting can never leave the table displaying a stale target.
Every check is evaluated on every bar, not just the last one, so the chart background can be shaded across the whole history wherever the symbol met a threshold you set. That turns a snapshot into a timeline: you can see which stretches of a stock's past actually satisfied CAN SLIM and which did not.
This is a checker, not a signal generator. It plots no entries, no arrows, no alerts. It answers one question - how much of CAN SLIM does this stock actually satisfy right now, and when has it satisfied it before - and shows its working.
WHERE CAN SLIM COMES FROM
CAN SLIM is the growth-stock methodology William J. O'Neil set out in "How to Make Money in Stocks" (1988), derived from a study of the biggest US stock market winners going back to the 1950s. It is an acronym for seven characteristics those winners shared before their major advances:
This script implements each letter as one or more concrete tests. Where O'Neil's criterion cannot be computed from data Pine Script can reach, the row says so instead of substituting something weaker and calling it a pass.
HOW EACH LETTER IS CALCULATED
C - Current quarterly earnings
Quarterly EPS (diluted by default, basic as fallback) against the same quarter a year ago, and the same for revenue. Optionally the prior quarter must clear the threshold too, because O'Neil wanted a run of strong quarters rather than one good print. A loss turning into a profit has no percentage growth rate, so it is detected separately and counted as a pass. A fourth row shows whether growth is accelerating quarter over quarter - O'Neil's ideal, not his floor, so it is informational and never scored.
Reaching "four reports ago" needs care. request.financial() returns step series that only change when a filing posts, so the usual change-detection trick fails silently whenever two consecutive reports carry an identical value - which share counts do constantly:
Pine Script®
A - Annual earnings
Annual EPS growth in each of the last three fiscal years, all three required. Return on equity from the latest annual report. Debt-to-equity computed from TOTAL_DEBT / TOTAL_EQUITY rather than the packaged ratio field so the units are unambiguous, displayed alongside its own value a year earlier, because O'Neil cared about the direction of leverage as much as the level.
N - New high
Distance below the 52-week high on daily bars, upgrading to NEW HIGH when today sets one. Two informational companions: breakout volume against the 50-day average (only meaningful within 2% of the high), and distance above the 50-day MA as a climax warning - a stand-in for O'Neil's "never chase more than 5% past the pivot", since Pine cannot locate a pivot without base detection.
S - Supply and demand
Free-float share count, share-count change year over year (buybacks pass, dilution fails), and the up/down volume ratio: volume on up-closes divided by volume on down-closes over the lookback.
L - Leader
Three tests:
I - Institutional sponsorship
This one is honestly not computable. request.financial() exposes no ownership, fund-count or 13F data, so the row is permanently gray and excluded from the score rather than faked. A liquidity proxy sits beside it - 50-day average dollar volume and a minimum share price - which establishes that institutions COULD hold it, not that they ARE buying it.
M - Market direction
Three rows feeding a three-state gate:
Those three produce a state rather than a boolean, because "not a confirmed uptrend" and "get out" are different instructions:
By default a correction stamps the score row regardless of how good the stock looks, which is what O'Neil meant when he called M the most important letter.
THE BACKGROUND SHADING
The chart is shaded on every bar where the symbol met a CAN SLIM bar you define, so the qualifying windows are visible across history instead of only the latest reading. An optional second shade marks bars where the stock cleared your bar but the market gate vetoed it - the setups worth remembering, where the stock was ready and the tape was not.
Three conditions must all hold, and the third is the one that matters:
Unresolved rows leave the denominator rather than counting as failures, which is correct for a checker but has a nasty consequence for shading: a symbol with almost no reported financials posts a clean 3 / 3 and would shade its entire chart green on nothing at all. The coverage floor refuses to shade until enough checks actually resolved. Without it the shading would be brightest exactly where the data is thinnest, which is the opposite of useful. Keep that floor high.
What the shading is, and what it is not. It is honest about time: request.financial() delivers each figure on its publication date, so a bar in 2019 only ever sees numbers that were public in 2019. There is no lookahead and the green stretches are real. It is not a backtest. It says "this symbol met your bar here", never "buying here worked" - no entry, no exit, no position and no return is implied or computed anywhere in this script.
Turning the market-gate requirement off is worth doing deliberately: it shows whether a name held up THROUGH a correction, which is where O'Neil looked for the next cycle's leaders.
HOW TO USE IT
Best used as the last filter before a watchlist entry, or as a post-mortem on a position that is not working. It will not find candidates for you - point it at names you already like.
SETTINGS
C - Current Quarterly Earnings
A - Annual Earnings Growth
N - New High
S - Supply & Demand
L - Leader
I - Institutional (proxy only)
M - Market Direction
Background Shading
Display
LIMITATIONS - READ THESE
NOTES
Open source - read the code. The header comment documents every design decision and every place a shortcut was taken. Built in Pine Script v6.
This is a research and education tool. It is not financial advice, not a recommendation to buy or sell anything, and no combination of green rows or green bars predicts a future price. CAN SLIM is a rules framework for narrowing a universe, not a system with an edge you can automate. Do your own work.
A single diagnostic table that scores the chart's symbol against William O'Neil's CAN SLIM criteria - 17 pass/fail checks plus 4 informational rows - and tells you plainly which ones it clears, which it fails, and which cannot be evaluated because the data does not exist.
Every row shows three things: the actual value, the threshold it has to clear, and the verdict. The threshold string is generated from the same input the pass/fail test reads, so retuning a setting can never leave the table displaying a stale target.
Every check is evaluated on every bar, not just the last one, so the chart background can be shaded across the whole history wherever the symbol met a threshold you set. That turns a snapshot into a timeline: you can see which stretches of a stock's past actually satisfied CAN SLIM and which did not.
This is a checker, not a signal generator. It plots no entries, no arrows, no alerts. It answers one question - how much of CAN SLIM does this stock actually satisfy right now, and when has it satisfied it before - and shows its working.
WHERE CAN SLIM COMES FROM
CAN SLIM is the growth-stock methodology William J. O'Neil set out in "How to Make Money in Stocks" (1988), derived from a study of the biggest US stock market winners going back to the 1950s. It is an acronym for seven characteristics those winners shared before their major advances:
- C - Current quarterly earnings up sharply. O'Neil's floor: +25% year over year; he preferred 40%+.
- A - Annual earnings growth of 25%+ in each of the last three years, with return on equity of 17%+.
- N - Something New: a new product, new management, or a new price high. O'Neil bought new highs, not bargains.
- S - Supply and demand: a smaller float moves further on the same demand, and volume should be flowing in on up days.
- L - Leader, not laggard: buy the best-performing stocks, not the cheap ones.
- I - Institutional sponsorship: funds should be accumulating it.
- M - Market direction: three of four stocks follow the market, so nothing else matters in a correction.
This script implements each letter as one or more concrete tests. Where O'Neil's criterion cannot be computed from data Pine Script can reach, the row says so instead of substituting something weaker and calling it a pass.
HOW EACH LETTER IS CALCULATED
C - Current quarterly earnings
Quarterly EPS (diluted by default, basic as fallback) against the same quarter a year ago, and the same for revenue. Optionally the prior quarter must clear the threshold too, because O'Neil wanted a run of strong quarters rather than one good print. A loss turning into a profit has no percentage growth rate, so it is detected separately and counted as a pass. A fourth row shows whether growth is accelerating quarter over quarter - O'Neil's ideal, not his floor, so it is informational and never scored.
Reaching "four reports ago" needs care. request.financial() returns step series that only change when a filing posts, so the usual change-detection trick fails silently whenever two consecutive reports carry an identical value - which share counts do constantly:
A - Annual earnings
Annual EPS growth in each of the last three fiscal years, all three required. Return on equity from the latest annual report. Debt-to-equity computed from TOTAL_DEBT / TOTAL_EQUITY rather than the packaged ratio field so the units are unambiguous, displayed alongside its own value a year earlier, because O'Neil cared about the direction of leverage as much as the level.
N - New high
Distance below the 52-week high on daily bars, upgrading to NEW HIGH when today sets one. Two informational companions: breakout volume against the 50-day average (only meaningful within 2% of the high), and distance above the 50-day MA as a climax warning - a stand-in for O'Neil's "never chase more than 5% past the pivot", since Pine cannot locate a pivot without base detection.
S - Supply and demand
Free-float share count, share-count change year over year (buybacks pass, dilution fails), and the up/down volume ratio: volume on up-closes divided by volume on down-closes over the lookback.
L - Leader
Three tests:
- The stock holding above its own 50- and 200-day moving averages.
- The RS line (close divided by the index) at or near its own 52-week high. O'Neil's ideal breakout has the RS line making a new high with or before price.
- An IBD-weighted 12-month momentum score - 40% on the 3-month return, 20% each on the 6/9/12-month legs - required to beat the index's own score.
I - Institutional sponsorship
This one is honestly not computable. request.financial() exposes no ownership, fund-count or 13F data, so the row is permanently gray and excluded from the score rather than faked. A liquidity proxy sits beside it - 50-day average dollar volume and a minimum share price - which establishes that institutions COULD hold it, not that they ARE buying it.
M - Market direction
Three rows feeding a three-state gate:
- Index structure - the market symbol above its 21-day EMA and 50-day SMA, with the 50 above the 200. Deliberately slow; this is the "is the tide in" question.
- Power Trend - IBD's own rule set, and the reason a plain fast-MA cross is the wrong tool for a market gate. It turns ON only when four conditions hold simultaneously: the index LOW has stayed above the 21-day EMA for 10 straight sessions (not merely the close - the index has not even dipped to it), the 21-EMA has held above the 50-SMA for 5 sessions, the 50-SMA is rising, and today closed up. It ends on a 21/50 cross back down, or on a circuit breaker: a close under the 50-SMA while already 10% off the three-month high. Those persistence counters are what stop a fast pair of averages whipsawing the gate.
- Distribution days - index closing down 0.2%+ on volume higher than the previous session, counted over a rolling 25-session window, with days retired once the index rallies 5% above the close of that day. IBD treats 5-6 as a correction signal.
Those three produce a state rather than a boolean, because "not a confirmed uptrend" and "get out" are different instructions:
- CONFIRMED UPTREND - Power Trend on, distribution contained. Buy normally.
- UNDER PRESSURE - One of those failing but the index still holds its 50-day. Smaller size, best setups only.
- CORRECTION - Power Trend off with the 50-day lost, or distribution past the danger threshold. The one O'Neil said to sit out.
By default a correction stamps the score row regardless of how good the stock looks, which is what O'Neil meant when he called M the most important letter.
THE BACKGROUND SHADING
The chart is shaded on every bar where the symbol met a CAN SLIM bar you define, so the qualifying windows are visible across history instead of only the latest reading. An optional second shade marks bars where the stock cleared your bar but the market gate vetoed it - the setups worth remembering, where the stock was ready and the tape was not.
Three conditions must all hold, and the third is the one that matters:
- An absolute floor on the number of checks passed.
- A percentage floor on passed / evaluable.
- A data-coverage floor on how many checks resolved at all.
Unresolved rows leave the denominator rather than counting as failures, which is correct for a checker but has a nasty consequence for shading: a symbol with almost no reported financials posts a clean 3 / 3 and would shade its entire chart green on nothing at all. The coverage floor refuses to shade until enough checks actually resolved. Without it the shading would be brightest exactly where the data is thinnest, which is the opposite of useful. Keep that floor high.
What the shading is, and what it is not. It is honest about time: request.financial() delivers each figure on its publication date, so a bar in 2019 only ever sees numbers that were public in 2019. There is no lookahead and the green stretches are real. It is not a backtest. It says "this symbol met your bar here", never "buying here worked" - no entry, no exit, no position and no return is implied or computed anywhere in this script.
Turning the market-gate requirement off is worth doing deliberately: it shows whether a name held up THROUGH a correction, which is where O'Neil looked for the next cycle's leaders.
HOW TO USE IT
- Put it on a daily chart of an individual stock. Everything price- and volume-based is pulled from a daily request.security() on the chart's own symbol, so the moving averages, the 52-week high and the momentum legs stay correct on weekly, monthly and intraday charts too. One row - the RS line's own 52-week high - cannot be built that way and grays out on intraday charts rather than reporting a nonsense number.
- Read the market state row first. In a correction, the rest of the table is academic.
- Read the score as a fraction of what was resolvable, not out of 17. Gray rows leave the denominator rather than being waved through, so 13/13 on a symbol with no financial data means far less than 13/17.
- Set the shading thresholds to your own standard, then scroll back. The green stretches tell you how often and for how long this name has actually met that standard. The Shading row in the table explains why the current bar is or is not shaded, and how many bars the current run has lasted.
- Use the tooltips. Every row carries the rule it implements, its limitations, and why it fails when it fails. Hover the row name.
- Scrub the Data Window for raw numbers on a historical bar. The table itself always reflects the most recent bar.
Best used as the last filter before a watchlist entry, or as a post-mortem on a position that is not working. It will not find candidates for you - point it at names you already like.
SETTINGS
C - Current Quarterly Earnings
- Use diluted EPS (on) - Diluted accounts for options and convertibles; basic flatters heavy issuers. Falls back to basic when diluted is unavailable.
- Min EPS YoY growth (FQ) % (25) - O'Neil's stated floor. He preferred 40%+.
- Require the prior quarter to clear it too (on) - Demands a run of quarters, not one print.
- Min Sales YoY growth (FQ) % (20) - EPS growth without revenue behind it is cost-cutting.
A - Annual Earnings Growth
- Min annual EPS growth, each of last 3 years % (25) - All three years must clear it.
- Min Return on Equity % (17) - O'Neil's efficiency threshold.
- Max Debt / Equity (1.0) - Industry-dependent. Utilities and REITs fail this by construction.
N - New High
- Max distance below 52-week high % (15) - The buyable zone: basing near highs, not repairing damage.
- Min share price (10) - Institutions largely cannot buy below this. Folded into the liquidity row rather than scored separately.
- Breakout volume vs 50-day avg (x) (1.4) - O'Neil wanted 40-50%+ above average on the breakout. Informational.
- Climax warning: % above 50-day MA (12) - Proxy for "too extended to start". Informational.
S - Supply & Demand
- Max float (millions of shares) (100) - O'Neil's 1988 examples used under 25M; floats have inflated since.
- Max shares-outstanding growth YoY % (2) - New supply works against the holder.
- Up/Down volume lookback (daily bars) (50) - Window for the accumulation ratio.
- Min U/D volume ratio (1.0) - 1.0 is neutral; real leaders usually read 1.25+.
L - Leader
- Max RS-line distance below its 52-week high % (5) - How close to a new RS high counts as leadership.
- Required momentum margin over index (0) - Zero means "merely beating the market", a low bar in a bear market. Raise it to demand real leadership.
I - Institutional (proxy only)
- Min avg daily dollar volume ($ millions) (20) - Depth at which funds CAN build a position. Not evidence that they are.
M - Market Direction
- Market index (AMEX:SPY) - SPY rather than SPX because distribution days need volume and SPX has none. Use QQQ for tech-heavy portfolios.
- Distribution-day window (days) (25) - IBD's trailing count.
- Max distribution days (4) - Pass threshold.
- Distribution-day decline threshold % (0.2) - How far down counts as distribution.
- Expire a distribution day after a rally of % (5) - IBD retires days the index has rallied past. Set 0 to count purely by age.
- Power Trend: days the low must hold above the 21-EMA (10) - Persistence condition 1.
- Power Trend: days the 21-EMA must hold above the 50-SMA (5) - Persistence condition 2.
- Power Trend circuit breaker: % below 3-month high (10) - The rare early exit in a fast decline.
- Distribution days that force a correction call (6) - Above the pass threshold but at or below this reads UNDER PRESSURE; beyond it, CORRECTION.
- Treat M as a gate (on) - Off makes M ordinary points in the score.
- Gate blocks when the market is (Correction only) - Or "Correction or Under Pressure" for a stricter stance.
Background Shading
- Shade the chart while the score qualifies (on) - Paints the background on every bar meeting the criteria below.
- Min checks passed (12) - Absolute floor, out of 17 scored checks. The main dial.
- Min % of evaluable checks passed (70) - Ratio floor on top of the absolute one. Both must be satisfied.
- Min evaluable checks, data coverage floor (12) - The guard that makes this honest. Refuses to shade until enough checks actually resolved, so a symbol with no reported financials cannot shade green on a 3 / 3. Keep it high.
- Also require the market gate to allow buying (on) - Applies the same three-state gate the score row uses. Off judges the stock alone.
- Shade differently when only the market blocks it (on) - A second shade for bars where the stock cleared your bar and the market vetoed it.
- Qualifying shade / Stock-only shade - Colour pickers, so you can tune them to your chart theme.
Display
- Table position (Top right) - Five anchor points.
- Layout (Full) - Full = all 21 rows, 5 columns, plus the Shading status row. Compact = 17 scored rows, shortened labels, informational rows dropped. Minimal (phone) = one row per CAN SLIM letter with that letter's tally, 9 rows total. The score and the shading are identical in all three - layouts hide rows, they do not skip arithmetic.
- Table text size (Small) - Auto scales to the chart pane, which is usually what you want on a phone.
- Show the "Needs" column (on) - The threshold column. Turning it off collapses the column rather than leaving an empty strip.
LIMITATIONS - READ THESE
- The shading is not a backtest and not a strategy. It marks bars where the symbol met a threshold you chose. No entry, exit, position or return is implied or computed anywhere in this script, and a long green stretch is not evidence that trading it would have worked.
- Institutional sponsorship cannot be evaluated. No ownership or 13F data exists in Pine. That row is permanently gray by design. Check IBD's Accumulation/Distribution rating or 13F filings directly.
- The L rows are not IBD's RS Rating. That rating is a percentile rank across the entire market; a Pine script sees one symbol at a time. The RS line and the weighted momentum score are single-symbol stand-ins, and beating the index is a floor, not a top-20% ranking.
- No base or pivot detection. There is no cup-with-handle recognition, no pivot point, no proper buy point. "Within 15% of the high" will keep passing stocks that are 14% down in a downtrend - pair it with the 50/200-day row before trusting it.
- Float is an annual figure. TradingView publishes FLOAT_SHARES_OUTSTANDING only as FY, so it can be up to a year stale, and it is missing outright for many symbols.
- Annual rows need history. Three years of annual growth requires four annual reports inside the chart's history - roughly five years of bars. Recent listings show gray, and the early years of any chart will sit unshaded for want of data rather than want of quality.
- Restatements are not modelled. Each figure appears on its publication date, which is what keeps the history free of lookahead, but a later revision is not reflected back onto the bars it would have changed.
- Fundamentals are as reported by TradingView, which is GAAP. IBD works from adjusted operating earnings, so numbers will not match IBD's screens exactly.
- Non-equity symbols (indices, forex, crypto) have no financials at all. Most rows will be gray, the score will be small and meaningless, and the coverage floor will correctly refuse to shade anything.
- The current day's volume is still forming until the close, so the breakout-volume row and today's distribution-day count can move intraday.
NOTES
Open source - read the code. The header comment documents every design decision and every place a shortcut was taken. Built in Pine Script v6.
This is a research and education tool. It is not financial advice, not a recommendation to buy or sell anything, and no combination of green rows or green bars predicts a future price. CAN SLIM is a rules framework for narrowing a universe, not a system with an edge you can automate. Do your own work.
Script open-source
Dans l'esprit TradingView, le créateur de ce script l'a rendu open source afin que les traders puissent examiner et vérifier ses fonctionnalités. Bravo à l'auteur! Bien que vous puissiez l'utiliser gratuitement, n'oubliez pas que la republication du code est soumise à nos Règles.
Clause de non-responsabilité
Les informations et publications ne sont pas destinées à être, et ne constituent pas, des conseils ou recommandations financiers, d'investissement, de trading ou autres fournis ou approuvés par TradingView. Pour en savoir plus, consultez les Conditions d'utilisation.
Script open-source
Dans l'esprit TradingView, le créateur de ce script l'a rendu open source afin que les traders puissent examiner et vérifier ses fonctionnalités. Bravo à l'auteur! Bien que vous puissiez l'utiliser gratuitement, n'oubliez pas que la republication du code est soumise à nos Règles.
Clause de non-responsabilité
Les informations et publications ne sont pas destinées à être, et ne constituent pas, des conseils ou recommandations financiers, d'investissement, de trading ou autres fournis ou approuvés par TradingView. Pour en savoir plus, consultez les Conditions d'utilisation.