Language reference
Sift
A query language for candles. SQL’s structure and English’s readability, over 3,687 NSE instruments with daily history to 20 Aug 2026.
Overview#
The common case is one line with no ceremony. Everything else is optional.
close > ema(21)That is a complete query. It reads the latest bar of every stock in the universe and keeps the ones closing above their 21-day exponential moving average. There is no timeframe to declare, no latest to repeat, and no wrapper.
Compare the same three intents against Chartink, whose syntax makes you restate the timeframe on every single term:
| Intent | Chartink | Sift |
|---|---|---|
| Close above the 20 EMA | ( {cash} ( latest close > latest ema( latest close , 20 ) ) ) | close > ema(21) |
| Volume twice its 20-bar average | ( {cash} ( latest volume > 2 * latest sma( latest volume , 20 ) ) ) | volume > 2x avg(volume, 20) |
| RSI crossed 60 in the last 3 bars | not expressible | rsi(14) crossed above 60 within 3 bars |
| Within 2% of the 52-week high | manual max plus arithmetic | close within 2% of high_52w |
Sift is not Turing complete: no loops, no user-defined functions, no side effects. Every query is statically analysable, which is what lets the editor underline a mistake before you run anything and lets the engine bound the cost of a scan before it starts.
Query shape#
Five clauses, all optional, conventionally in this order.
on <timeframe>
from <universe>
where <condition>
sort by <expression> [asc | desc]
top <n>A bare condition is a complete query — where is optional. Clauses may appear in any order. Newlines and indentation carry no meaning, and # or // starts a comment that runs to the end of the line.
on daily
from NSE
where close > ema(21) > ema(50) # a trend in good order
and volume > 2x avg(volume, 20)
and delivery_pct > 55
sort by turnover desc
top 25| Clause | Purpose | Default |
|---|---|---|
| on | Candle timeframe. | daily — the only one this dataset carries |
| from | Which universe to scan: `NSE` (all equities) or `fno` (stocks with listed futures & options). | NSE |
| where | The condition. Optional keyword. | everything matches |
| sort by | Order the results by any expression. | turnover, descending |
| top | Row cap. | 300 |
sort by accepts any expression, not just a returned column — sort by (close - ema(50)) / ema(50) desc ranks by distance above the average.Fields#
Written bare, with no parentheses. Each maps to one precomputed column.
Price
| Field | Meaning |
|---|---|
| close | Closing price, adjusted for splits and bonuses. |
| open | Opening price. |
| high | Session high. |
| low | Session low. |
| hl2 | Midpoint of the session range. |
| hlc3 | Typical price. |
| ohlc4 | Average of all four session prices. |
| ha_open | Heikin-Ashi open — the average of the previous HA open and close. |
| ha_high | Heikin-Ashi high. |
| ha_low | Heikin-Ashi low. |
| ha_close | Heikin-Ashi close — the average of the bar's four prices. |
| high_52w | Highest high of the last 252 sessions. |
| low_52w | Lowest low of the last 252 sessions. |
| pct_from_52w_high | Distance below the 52-week high, as a negative percentage. |
| pct_from_52w_low | Distance above the 52-week low, as a percentage. |
| pivot | Classic floor-trader pivot from the previous session. |
| pivot_r1 | First resistance above the pivot. |
| pivot_r2 | Second resistance above the pivot. |
| pivot_s1 | First support below the pivot. |
| pivot_s2 | Second support below the pivot. |
Volume & delivery
| Field | Meaning |
|---|---|
| volume | Shares traded. |
| turnover | Close × volume, in rupees. |
| trades | Number of trades executed. |
| delivery_pct | Share of volume taken to demat rather than squared off intraday. High delivery on a rising day suggests genuine accumulation. |
| delivery_qty | Shares taken to demat. |
| rel_volume | Volume divided by its own 20-day average. 2 means twice normal. |
| obv | Running total of volume signed by the day's direction. |
| acc_dist | Running total weighted by where the close sits in the range. |
| cmf | Accumulation/distribution normalised over 20 bars. Positive means buying pressure. |
| force_index | Price change times volume, smoothed over 13 bars. |
Momentum
| Field | Meaning |
|---|---|
| stoch_k | Slow stochastic %K over 14 bars, smoothed by 3. |
| stoch_d | 3-bar average of stochastic %K. |
| stoch_rsi | The stochastic oscillator applied to RSI itself. |
| cci | Commodity Channel Index over the typical price. |
| williams_r | Like the stochastic, scaled −100 to 0. |
| mfi | A volume-weighted RSI over the typical price. |
| roc | Percentage change over 10 bars. |
Trend
| Field | Meaning |
|---|---|
| adx | Trend strength, direction-agnostic. Above 25 is usually read as trending. |
| di_plus | Positive directional indicator. |
| di_minus | Negative directional indicator. |
| supertrend | ATR-banded trailing stop (10, 3). |
| supertrend_dir | +1 while Supertrend is bullish, −1 while bearish. |
| psar | Parabolic stop-and-reverse (0.02, 0.2). |
| aroon_up | How recently the 25-bar high occurred. |
| aroon_down | How recently the 25-bar low occurred. |
| aroon_osc | Aroon up minus Aroon down. |
| ichimoku_conversion | Tenkan-sen, the 9-bar midpoint. |
| ichimoku_base | Kijun-sen, the 26-bar midpoint. |
| ichimoku_span_a | Cloud edge A, unshifted. |
| ichimoku_span_b | Cloud edge B, unshifted. |
Volatility
| Field | Meaning |
|---|---|
| atr | Wilder's average true range over 14 bars. |
| true_range | This bar's true range. |
| bb_upper | 20-period SMA plus two standard deviations. |
| bb_mid | 20-period simple moving average. |
| bb_lower | 20-period SMA minus two standard deviations. |
| bb_pct_b | Where the close sits within the bands: 0 at the lower, 1 at the upper. |
| bb_width | Band separation as a fraction of the middle band. Low means a squeeze. |
| donchian_upper | Highest high of the last 20 bars. |
| donchian_mid | Midpoint of the Donchian channel. |
| donchian_lower | Lowest low of the last 20 bars. |
| keltner_upper | 20-EMA plus two ATRs. |
| keltner_lower | 20-EMA minus two ATRs. |
Performance
| Field | Meaning |
|---|---|
| change | Percentage change against the previous close. |
| return_1w | Percentage change over 5 sessions. |
| return_1m | Percentage change over 21 sessions. |
| return_3m | Percentage change over 63 sessions. |
| return_6m | Percentage change over 126 sessions. |
| return_1y | Percentage change over 252 sessions. |
Derivatives (F&O)
| Field | Meaning |
|---|---|
| fut_oi | Total futures open interest across all expiries, in contracts. |
| fut_oi_change_pct | Day-over-day change in total futures OI. Read it with price: price up with OI up is long buildup, price down with OI up is short buildup. The drop after an expiry day is genuine, not noise. |
| fut_volume | Futures contracts traded across all expiries. |
| fut_basis_pct | Front-month futures premium (positive) or discount (negative) to the cash price, in percent. Compared on the raw price scale — corporate actions are bridged out. Reads near zero on expiry day by construction. |
| fut_rollover_pct | Share of futures OI already sitting in later expiries. On expiry day this is the classic rollover number the derivatives desks quote. |
| pcr_oi | Put OI divided by call OI across this stock's options, all expiries. Above 1 means more open puts than calls. NULL when no calls are open. |
| pcr_vol | Put contracts traded divided by call contracts traded, all expiries. |
Fundamentals
| Field | Meaning |
|---|---|
| marketcap | Close times shares outstanding, in rupees — write `marketcap > 5000cr`. The share count is restated onto the adjusted-price basis, so a split does not fake a jump. |
| pe | Price to trailing-twelve-month earnings, from the last four filed quarters as known on that date. NULL when TTM earnings are negative or not yet filed — a loss-maker has no P/E rather than a misleading one. |
| eps_ttm | Trailing-twelve-month earnings per share, split-adjusted to match the adjusted price series (filed EPS is not — it is never used directly). Negative for loss-makers, NULL until four consecutive quarters are on file. |
| revenue_growth_yoy | Latest filed quarter's revenue against the same quarter last year. |
| profit_growth_yoy | Latest filed quarter's net profit against the same quarter last year. NULL when the base quarter was a loss — growth from negative earnings is not a number. |
| revenue_growth_qoq | Latest filed quarter's revenue against the previous quarter. |
| profit_growth_qoq | Latest filed quarter's net profit against the previous quarter. NULL when the base quarter was a loss. |
| profit_cagr_2y | Annualized growth in trailing-twelve-month net profit over two years — the shortest window where compounding says anything a single YoY does not. |
| profit_cagr_3y | Annualized growth in trailing-twelve-month net profit over three years. Wider coverage than the five-year window, and long enough to outlast one soft base year. |
| profit_cagr_4y | Annualized growth in trailing-twelve-month net profit over four years. |
| profit_cagr_5y | Annualized growth in trailing-twelve-month net profit over five years — the usual test of whether earnings compound or merely cycle. A company needs five unbroken years of filings on one basis to get a number; about half of covered names do. |
| profit_cagr_6y | Annualized growth in trailing-twelve-month net profit over six years. Sparse — few names have this much filed history yet. |
| profit_cagr_7y | Annualized growth in trailing-twelve-month net profit over seven years — the longest window the results store reaches, and the sparsest. |
| revenue_cagr_2y | Annualized growth in trailing-twelve-month revenue over two years. |
| revenue_cagr_3y | Annualized growth in trailing-twelve-month revenue over three years. |
| revenue_cagr_4y | Annualized growth in trailing-twelve-month revenue over four years. |
| revenue_cagr_5y | Annualized growth in trailing-twelve-month revenue over five years. Pair it with `profit_cagr_5y` to separate operating leverage from growth that only arrived through the top line. |
| revenue_cagr_6y | Annualized growth in trailing-twelve-month revenue over six years. |
| revenue_cagr_7y | Annualized growth in trailing-twelve-month revenue over seven years. |
| interest_cost_growth_yoy | Trailing-twelve-month finance costs against a year earlier. This is a proxy for the direction of borrowing, not a measure of it: quarterly filings carry a P&L and no balance sheet, so there is no debt figure here to read — flat interest beside growing profit is the shape of growth funded from earnings, and a jump is the shape of fresh debt. Read it against `pe` and a profit CAGR, exclude lenders (for a bank interest is the cost of goods, not leverage), and expect NULL when a quarter's finance-cost line is missing. |
| promoter_pct | Promoter shareholding from the latest pattern filed by that date. |
| public_pct | Public shareholding from the latest pattern filed by that date. |
| fii_pct | Foreign institutional holding from the latest pattern filed by that date. Sparse until the shareholding XBRL backfill completes. |
| dii_pct | Domestic institutional holding from the latest pattern filed by that date. Sparse until the shareholding XBRL backfill completes. |
| promoter_pledged_pct | Share of the promoter stake pledged as collateral. Zero is the healthy reading; a rising number is the classic distress tell. |
| promoter_change_qoq | Percentage-point change in promoter holding against the previous quarter's pattern. Positive means promoters bought. |
price is accepted as an alias for close, so price between 50 and 5000 reads naturally.Sectors & categories#
Closed sets of string values, tested with `is`, `is not` and `in`.
where sector is "Information Technology"
and pe < 25 and pe > 0| Form | Meaning |
|---|---|
| sector is "Information Technology" | Exactly this NSE sector. |
| sector is not "Financial Services" | Everything but this sector. |
| industry in ("Banks", "Finance") | Any of the listed industries. |
| macro_sector is "Consumer Discretionary" | The broadest tier, above sector. |
The values are NSE’s official classification — 22 sectors, 12 macro sectors, 58 industries — and the editor autocompletes them after is, so nobody has to remember that the exact spelling is “Oil Gas & Consumable Fuels”. Matching is case-insensitive; the compiler canonicalises onto the official name.
Derivatives#
Per-stock daily aggregates from the NSE F&O bhavcopy, for the roughly 200 stocks with listed futures & options.
from fno where fut_oi_change_pct > 3 and change > 1Price and open interest rising together is a long buildup — fresh money agreeing with the move, rather than shorts giving up. Open interest is in contracts, summed across all expiries, because contracts are the unit NSE actually publishes.
| Field | Meaning |
|---|---|
| fut_oi | Total futures open interest, in contracts. |
| fut_oi_change_pct | Day-over-day change in futures OI. Rising OI with rising price is a long buildup. |
| fut_volume | Futures contracts traded. |
| fut_basis_pct | Front-month futures premium (+) or discount (−) to cash. |
| fut_rollover_pct | Share of OI already in later expiries. |
| pcr_oi | Put-call ratio by open interest. |
| pcr_vol | Put-call ratio by contracts traded. |
from fno where pcr_oi > 0.8 and close > sma(50)from fno makes that scope explicit — writing an F&O field without it earns a compiler warning rather than a silently thin result.Fundamentals#
Valuation, growth and shareholding, as the market knew them on the scan date.
where marketcap > 20000cr and pe < 30 and pe > 0Fundamentals are point-in-time. A result filed after the 15:30 close becomes visible from the next session, and a restatement counts only from its own filing date — so a scan on any past date sees exactly what a trader could have known that day, never what the filings later became. That is what keeps the hit-rate replay honest for fundamental screens.
| Field | Meaning |
|---|---|
| marketcap | Close × shares outstanding, in rupees — `marketcap > 5000cr`. |
| pe | Price to trailing-twelve-month earnings. NULL for loss-makers rather than a misleading number. |
| eps_ttm | Trailing EPS, split-adjusted to match the adjusted price series. |
| revenue_growth_yoy / profit_growth_yoy | Latest filed quarter against the same quarter last year. |
| revenue_growth_qoq / profit_growth_qoq | Latest filed quarter against the previous quarter. |
| profit_cagr_2y … profit_cagr_7y | Annualized profit growth over N years, trailing twelve months against the TTM N years earlier. NULL when the history is short or either end was a loss. |
| revenue_cagr_2y … revenue_cagr_7y | The same window on revenue — pair with the profit CAGR to see whether margins widened or only sales did. |
| interest_cost_growth_yoy | TTM finance costs against a year ago. A proxy for the direction of borrowing, not a debt figure — quarterly filings carry no balance sheet. |
| promoter_pct / public_pct / fii_pct / dii_pct | Shareholding from the latest pattern filed by the scan date. |
| promoter_pledged_pct | Share of the promoter stake pledged as collateral. |
| promoter_change_qoq | Percentage-point change in promoter holding vs the previous quarter. |
where promoter_change_qoq > 0.5 and close > sma(200)Indicators#
Called with a period. The source series defaults to close.
where rsi(14) < 40 and close > sma(200)| Indicator | Periods | Meaning |
|---|---|---|
| sma(n) | 5, 10, 20, 50, 100, 200, any | Unweighted mean close over the period. |
| ema(n) | 9, 21, 50, 200, any | Exponentially weighted mean close, seeded from the SMA. |
| wma(n) | 20, any | Linearly weighted mean — the newest bar counts most. |
| hma(n) | 21, any | Hull's low-lag moving average. |
| tema(n) | 20, any | Triple-smoothed EMA, with much of the lag removed. |
| rma(n) | 14, any | Wilder's smoothing, as used inside RSI and ATR. |
| vwma(n) | 20, any | Mean close weighted by each bar's volume. |
| rsi(n) | 14, any | Wilder's relative strength index. |
| atr(n) | 14, any | Wilder's average true range. |
| adx(n) | 14, any | Trend strength, direction-agnostic. |
| cci(n) | 20, any | Commodity Channel Index. |
| mfi(n) | 14, any | Volume-weighted RSI. |
| cmf(n) | 20, any | Accumulation/distribution normalised over a window. |
| roc(n) | 10, any | Percentage change over the period. |
| williams_r(n) | 14, any | Like the stochastic, scaled −100 to 0. |
Every indicator accepts any period: the listed ones read a precomputed column and anything else is computed at scan time, so ema(37), adx(7) and bb(50, 2.5) all work. Multi-output indicators take their full parameter list — macd(8, 21, 5), supertrend(14, 2) — and written bare, macd() keeps meaning the stored 12/26/9.
Multi-output indicators
Indicators producing more than one line take empty parentheses and a sub-field. Omitting the sub-field picks the one shown in bold.
where macd().line crosses above macd().signal
and close > bb().upper| Indicator | Sub-fields | Meaning |
|---|---|---|
| macd() | .line .signal .hist | 12/26 EMA difference, with a 9-period signal line. |
| bb() | .upper .mid .lower .pctb .width | 20-period SMA with two-standard-deviation bands. |
| stoch() | .k .d | Slow stochastic oscillator. |
| supertrend() | .value .dir | ATR-banded trailing stop. |
| donchian() | .upper .mid .lower | The rolling 20-bar high/low envelope. |
| keltner() | .upper .lower | A 20-EMA with ATR-scaled bands. |
| ichimoku() | .conversion .base .span_a .span_b | Conversion, base and cloud edges. |
| aroon() | .up .down .osc | How recently the window's extremes occurred. |
Window functions#
Rolling aggregates over any period, computed at scan time rather than read from a column.
where volume > 2x avg(volume, 20)
and close > max(high, 20 bars)[-1]| Function | Returns |
|---|---|
| avg(x, n) | Mean of x over the last n bars. |
| max(x, n) | Highest value of x over the last n bars. |
| min(x, n) | Lowest value of x over the last n bars. |
| sum(x, n) | Total of x over the last n bars. |
| stdev(x, n) | Population standard deviation of x. |
| median(x, n) | Median of x over the last n bars. |
The window takes a bar count or a duration — avg(volume, 20), max(high, 20 bars) and min(low, 52w) are all valid. The first argument is any expression, so avg(high - low, 10) gives the mean daily range.
avg(close, 50) and sma(50) agree exactly rather than differing on new listings.Time travel#
Past bars are negative. There is no future.
| Written | Means |
|---|---|
| close | This bar — the scan date. |
| close[-1] | The previous bar. |
| prev close | The previous bar, spelled out. |
| close[-5] | Five bars ago. |
| avg(volume, 20)[-1] | The 20-bar average as of yesterday. |
where open > high[-1] and close > openclose[1] would name a bar that has not happened, and silently treating it as the past is how look-ahead bias gets into a scan.Operators#
The usual comparisons and arithmetic, plus chaining.
| Operators | Notes |
|---|---|
| > >= < <= = != | `=` is accepted as `==`. |
| + - * / | Division by zero yields no value rather than an error. |
| and or not | `and` binds tighter than `or`. Parenthesise when mixing. |
| ( ) | Grouping, for both conditions and arithmetic. |
Chained comparisons
A chain means what it looks like — each neighbouring pair must hold.
where close > ema(21) > ema(50) > ema(200)That is exactly equivalent to writing the three comparisons out and joining them with and.
Sugar#
Shorthand for the arithmetic other screeners force you to write by hand.
| Written | Equivalent to |
|---|---|
| 2x avg(volume, 20) | 2 * avg(volume, 20) |
| 5% above ema(50) | ema(50) * 1.05 |
| 3% below sma(200) | sma(200) * 0.97 |
| close within 2% of high_52w | close between high_52w*0.98 and high_52w*1.02 |
| price between 50 and 5000 | price >= 50 and price <= 5000 |
| close up 3% over 5 bars | (close - close[-5]) / close[-5] >= 0.03 |
| close down 2% over 5 bars | (close[-5] - close) / close[-5] >= 0.02 |
These are not approximations. Each form is checked against its longhand equivalent in the test suite and must select exactly the same stocks.
Event operators#
Crossings, persistence, runs and extremes — the reason the language exists.
Every one of these compiles to a bounded window expression. In a screener without them you would hand-roll the same thing out of offset arithmetic, and get it subtly wrong.
Crossings
where sma(50) crosses above sma(200)A crossing is defined on two bars: strictly across now, and not across on the bar before. Add a recency window to catch one that happened a few sessions ago.
where rsi(14) crossed above 30 within 3 bars
and close > sma(200)Persistence
Whether something has held for a stretch, rather than being true on one lucky day.
where close has been above ema(21) for 10 bars and adx > 25Monotonic runs
where volume rising for 3 bars and close > close[-3]Window extremes
is highest in compares against a window that includes the current bar, so it is true exactly when this bar sets the extreme.
where close is highest in 52w and volume > 1.5x avg(volume, 20)| Form | True when |
|---|---|
| x crosses above y | x is above y now and was at or below on the previous bar. |
| x crosses below y | x is below y now and was at or above on the previous bar. |
| x crossed above y within n bars | That crossing happened on any of the last n bars. |
| x has been above y for n bars | x was above y on every one of the last n bars. |
| x rising for n bars | x increased on each of the last n bars. |
| x falling for n bars | x decreased on each of the last n bars. |
| x is highest in n | No bar in the window has a higher x. |
| x is lowest in n | No bar in the window has a lower x. |
Candlestick patterns#
Detected at build time and queried as a first-class value.
where pattern is bullish_engulfing
and close within 3% of sma(50)Add within n bars for recency, or pattern is not … to exclude one. Definitions use proportional tolerances, so they behave the same on a ₹30 stock and a ₹30,000 one.
| Pattern | Shape |
|---|---|
| doji | Open and close nearly equal — indecision. |
| hammer | Long lower wick, small body at the top. |
| shooting_star | Long upper wick, small body at the bottom. |
| marubozu | Almost no wicks — one side controlled the session. |
| bullish_engulfing | An up bar whose body swallows the previous down bar. |
| bearish_engulfing | A down bar whose body swallows the previous up bar. |
| bullish_harami | A small up bar contained inside the previous down bar. |
| bearish_harami | A small down bar contained inside the previous up bar. |
| morning_star | Down bar, pause, then a strong up bar through the midpoint. |
| evening_star | Up bar, pause, then a strong down bar through the midpoint. |
| three_white_soldiers | Three consecutive strong up bars. |
| three_black_crows | Three consecutive strong down bars. |
| inside_bar | Range contained entirely within the previous bar's. |
| outside_bar | Range containing the whole previous bar's. |
Numbers & literals#
Indian and Western magnitudes, both native.
| Written | Value |
|---|---|
| 1k | 1,000 |
| 5L | 5,00,000 — five lakh |
| 2.5m | 25,00,000 |
| 10cr | 10,00,00,000 — ten crore |
| 1b | 100,00,00,000 |
| ₹500 / $50 | 500 / 50 — the symbol is read and discarded |
| 20 bars / 52w / 3mo / 2y | A duration, converted to trading sessions |
where turnover > 10cr and volume > 5LDurations convert at roughly 5 sessions a week and 252 a year, so 52w is 260 bars and 1y is 252.
Universes#
Which stocks a scan considers, chosen in the toolbar rather than in the query.
| Tier | Contains |
|---|---|
| Top 100 | Most traded 100 stocks by 20-day turnover |
| Top 250 | Most traded 250 stocks by 20-day turnover |
| Top 500 | Most traded 500 stocks by 20-day turnover |
| Top 1000 | Most traded 1000 stocks by 20-day turnover |
| All equities | Every actively traded NSE equity |
marketcap field for conditions, but the tiers stay turnover-ranked because turnover is dense from day one while fundamentals coverage is still filling in.from fno narrows a scan to the roughly 200 stocks with listed futures & options — the set the derivatives fields cover.
from fno where fut_oi_change_pct > 10 and close up 2% over 1 barsErrors#
Every mistake is reported with the reason and the fix, before the scan runs.
The parser and analyser run in the browser as you type — they are pure and need no database — so the editor underlines a problem immediately, and the identical code validates again on the server.
| Written | Reported as |
|---|---|
| clos > 100 | Unknown field `clos` — Did you mean `close`? |
| sma > 100 | `sma` needs a period — Try `sma(5)`, `sma(10)`, `sma(20)`. |
| rsi(1000) > 50 | `rsi` period must be between 2 and 400 — e.g. `rsi(14)`. |
| close[1] > 100 | `[1]` looks like a future bar — write `[-1]` for one bar ago. |
| rsi(14) crosses 30 | `crosses` must be followed by `above` or `below`. |
| on 15m where close > 100 | Timeframe `15m` is not available — this dataset is end-of-day only. |
| pattern is wibble | Unknown pattern `wibble`. |
| macd().wibble > 0 | `macd()` has no sub-field `wibble` — Available: line, signal, hist. |
Recipes#
Complete scans worth stealing. Each one runs.
52-week high breakout
Closing at a fresh 52-week high on above-average volume — the classic Darvas-style entry.
where close is highest in 52w and rel_volume > 1.5Within 3% of the 52-week high
Coiling just under the highs. Often a better entry than the breakout candle itself.
where close within 3% of high_52w and close > ema(50)Volume breakout
Twice normal volume with price up more than 3% — something changed today.
where volume > 2x avg(volume, 20)
and change > 3
and close > sma(20)Volume shockers
Twice the ten-day average volume with a move of more than 5% — the day something happened.
where volume > 2x avg(volume, 10) and change > 520-day channel breakout
Pushing through the top of the 20-day range with volume behind it.
where close > donchian_upper[-1]
and volume > 1.5x avg(volume, 20)Bollinger band breakout
Close pushing above the upper band, with volume confirming.
where close > bb().upper and rel_volume > 1.5Keltner channel breakout
Clearing the ATR-based upper channel — a steadier breakout signal than Bollinger's.
where close > keltner_upper and rel_volume > 1.5Crossing above pivot R1
Price clearing the first pivot resistance on strong volume — a classic floor-trader level.
where close crosses above pivot_r1 and rel_volume > 1.5The scan library has 115 of these, each testable against a year of history.
Data caveats#
What the newer data can and cannot honestly answer.
| Caveat | The honest version |
|---|---|
| F&O coverage | Roughly 200 NSE stocks have listed derivatives. Everywhere else the F&O fields are NULL and never match — `from fno` makes the scope explicit. |
| Fundamentals coverage | The filings backfill is in progress; a stock without parsed results has NULL P/E and growth, and never matches those conditions. Coverage rises weekly. |
| Institutional holdings | Promoter and public shares of equity are filed every quarter and are the two the shareholding view is built on. FII, DII, employee-trust and pledge percentages come from a separate filing stage whose backfill has reached about 1% of instruments — they are NULL almost everywhere, including for the largest companies on the exchange, and never match. |
| Quarterly results | The per-quarter profit and loss starts in 2017 and the shareholding pattern in 2015. NSE's quarterly filings carry a P&L only, so there is no balance sheet, cash flow, debt or return-on-capital figure anywhere in this dataset. |
| Sector history | Classification is today's snapshot — NSE publishes no history. A historical scan or hit-rate replay applies the current sector retroactively. |
| OI units | Open interest is in contracts, summed across expiries, both before and after a lot-size revision — the unit NSE actually publishes. |
Fundamentals are point-in-time: a scan sees the numbers as the market knew them on the scan date. A result filed after the 15:30 close becomes visible from the next session, and a restatement counts only from its own filing date — which is what keeps the hit-rate replay honest for fundamental screens.
Not supported#
Parts of the language spec this dataset cannot honour, and why.
| Feature | Why not |
|---|---|
| on 15m / 1h / weekly | The dataset is end-of-day only. `on daily` is the only timeframe. |
| from BSE / US / NIFTY500 | NSE only, and there is no index-constituent list to filter by. `from fno` is the one list-like universe. |
| vwap | Needs intraday data, which end-of-day bars cannot provide. |
| per-strike option screening | F&O fields are per-stock daily aggregates. Strike-level OI is a chain view, not a screener column. |
| pattern is … forming | Geometric pattern detection with a confidence score is not built. Only completed candlestick patterns are available. |
| backtest { } / alert { } | Not implemented. The hit-rate panel on each scan is the nearest thing. |
| top 10% by … | Percentile limits are rejected; use a plain count. |
API & MCP#
Everything on this page works without the browser.
A scan is one POST with the Sift source in the body, and the MCP endpoint gives a coding agent this whole reference as a tool — so Claude Code or Codex can write and run scans against your account unaided. Keys are free on every plan.