29 Aug 2026

Scanning the candle body, not the close

Most scans read the close and ignore the rest of the candle. abs(), greatest() and least() in Sift let a scan describe the body: its size against the stock's own norm, and where the whole of it sits. Three ready NSE scans.

close > sma(20) is true whether the stock opened far above the average and sold off all day to end just over it, or opened underneath and rallied through. Those are opposite sessions. A scan that reads the close alone cannot tell them apart, and for a long time neither could mine.

A candle has four prices. The body, open to close and ignoring the wicks, is the part of the session that got decided rather than merely visited. It takes one arithmetic function to put that into a scan.

The body's size

abs(close - open) is the body in rupees, in either direction. On its own that is useless across a universe where one stock trades at ₹40 and another at ₹4,000, so compare it against the stock's own norm:

where abs(close - open) > 2x avg(abs(close - open), 20)
Run

A body more than twice its own 20-day average size. The scale adapts to each name, because a 4% body is ordinary in a small-cap that swings around and extraordinary in a large-cap that does not. It says nothing about direction, which I consider a feature: a decisive down day carries as much information as a decisive up day.

The math functions compose with everything, which is what keeps that query to one line. abs(close - open) is a value, avg(…, 20) will take any value, and 2x is the same multiple sugar that works on volume. Sift has ten of these: abs, ceil, floor, round, square, sqrt, log, log10, greatest and least. The language reference lists them all. In practice abs and the last two do nearly all the work.

Where the body sits

greatest(open, close) is the top of the body and least(open, close) is its bottom, whichever way the candle went. That turns "the stock pulled back to between its two averages" from a statement about the close into a statement about the whole session:

where greatest(open, close) < sma(20)
  and least(open, close) > sma(50)
Run

The stock opened and closed under the 20-day, and opened and closed above the 50-day. A candle that pierced the 50-day in the morning and recovered does not qualify, because its least is under the line. Neither does one that spent the day above the 20 and dipped under it at the close. Only a session that lived entirely inside the band gets through. That is a far more specific pullback than close between sma(50) and sma(20), and a close-only screener has no way to describe it.

Three ready scans

Each is a preset you can open, run and edit. Every scan page carries a hit-rate replay over the past year of NSE sessions, close-to-close and without costs, so you can see what past matches did before relying on it.

Wide-body candle, the decisive session, biggest first:

where abs(close - open) > 2x avg(abs(close - open), 20)
  and rel_volume > 1.5
sort by abs(close - open) / open desc
Run

The volume condition separates a real repricing from a thin stock drifting a long way on nothing. The sort divides the body by the open to rank in percentage terms, so a ₹4,000 stock and a ₹40 stock get compared fairly. Read the direction off the sign of the day's change.

Candle between the 20 and 50, the whole-body pullback inside a trend:

where greatest(open, close) < sma(20)
  and least(open, close) > sma(50)
  and sma(50) > sma(200)
Run

The third line is the trend filter. I left it off the first time I wrote this one and got back a list of stocks passing through their averages on the way down.

Whipsaw stocks applies abs to the daily change rather than to the body:

where count(abs(change) > 3, 20) >= 5
Run

change is the day's percentage move. abs folds the two directions into one. count asks how many of the last twenty sessions moved more than 3% either way, and five or more is a stock being repriced violently and often. I use it mostly as a list of names to avoid, since a stop inside a 3% band on these is a coin toss. The count function has its own guide.

Alongside these, the older Marubozu on volume scan gets at body size through pattern detection instead. A marubozu is a candle that is nearly all body and no wick, and the detector finds it without any arithmetic. The two approaches answer different questions. The pattern answers "was this a conviction candle". The arithmetic answers "how big was it against this stock's own norm, and rank them for me".

Two things to know

Where a function is undefined, sqrt of a negative number or log of zero, it reads as empty rather than failing, so one odd row cannot abort a scan across the whole table. An empty value never matches a condition, which is the rule every other empty field follows.

A math call takes no bar offset. abs(close - open)[-1] is refused. The offset goes on the fields instead, abs(close[-1] - open[-1]), which is yesterday's body. One rule for where [-1] may appear beats two.