Qstick indicator: candle-body momentum
Qstick averages the difference between each candle's close and open. The SMA version is ta.sma(close - open, length). A positive reading means positive bodies outweigh negative bodies in price units. Gaps between bars are excluded, so Qstick can disagree with the direction of the closing prices.
Qstick(3) = (-1 - 1 + 4) / 3 = +0.6667
Two negative candles, one positive result. Body size matters; Qstick does not count winning candles.
Formula and zero-line meaning
For N valid bars, add their signed bodies and divide by N: Qstick = sum(close - open) / N. High, low and volume do not enter the calculation. A value of +0.50 means an average positive body of 0.50 price units, not a 0.50% return or a probability.
MotiveWave documents close minus open and a selectable moving average, with SMA as its default method. This guide uses SMA throughout. The default length of 14 in the code matches Pineify's configuration; it is not a standard shared by every Qstick implementation.
| Reading | What it establishes | What it does not establish |
|---|---|---|
| Above zero | The sum of signed bodies is positive. | Most bars were positive, or price rose over the window. |
| Below zero | The sum of signed bodies is negative. | The next bar will fall. |
| Rising below zero | The average becomes less negative. | The average body is already positive. |
| Cross above zero | Current average is positive; previous average was zero or negative. | A complete entry, exit or profitable strategy. |
A four-bar OHLC calculation with a large gap
These invented prices use a three-bar SMA. Assume no earlier history and a previous close of 100 before bar 1. High and low are included to make the candles inspectable, although Qstick ignores them.
| Bar | Open | High | Low | Close | Body | Qstick(3) |
|---|---|---|---|---|---|---|
| 1 | 100 | 101 | 97 | 98 | -2 | Not ready |
| 2 | 98 | 99 | 96 | 97 | -1 | Not ready |
| 3 | 110 | 111 | 108 | 109 | -1 | -1.3333 |
| 4 | 109 | 114 | 108 | 113 | +4 | +0.6667 |
At bar 3, Qstick is (-2 - 1 - 1) / 3 = -1.3333. Yet price has risen from the preceding close of 97 to 109. The +13 gap from 97 to 110 and the -1 body combine into a +12 close-to-close move. Qstick records only the -1 body.
At bar 4, the -2 body leaves the window and +4 enters. Qstick becomes (-1 - 1 + 4) / 3 = +0.6667 and crosses zero. Two of the three bodies remain negative. The change in Qstick is (+4 - (-2)) / 3 = +2, showing how an old observation leaving the window can affect the line.
Why it differs from Momentum
For the same N bars, close-to-close Momentum equals the sum of bodies plus the sum of gaps. At bar 3, Momentum(3) is 109 - 100 = +9: body sum -4 plus gap sum +13. If every open equals the preceding close, all gaps are zero and Qstick(N) = Momentum(N) / N. This is an algebraic identity under that assumption, not a claim that market data always satisfy it.
Compare the Momentum indicatorQstick Pine Script v6 with closed-bar crossings
Paste the complete example into TradingView Pine Editor, save it and add it to a standard candle chart. Change Length to 3 to check the arithmetic above on your own observations. The code is an indicator; it places no strategy orders.
//@version=6
indicator("Qstick: candle-body average", overlay = false, precision = 4)
length = input.int(14, "Qstick length in bars", minval = 1, maxval = 500)
body = close - open
qstick = ta.sma(body, length)
plot(qstick, "Qstick (price units)", color = color.blue, linewidth = 2)
hline(0, "Zero", color = color.gray)
plot(body, "Current candle body", display = display.data_window)
plot(open - close[1], "Gap from previous close", display = display.data_window)
crossUp = ta.crossover(qstick, 0)
crossDown = ta.crossunder(qstick, 0)
confirmedUp = crossUp and barstate.isconfirmed
confirmedDown = crossDown and barstate.isconfirmed
plotshape(confirmedUp, title = "Confirmed cross up", style = shape.triangleup, location = location.bottom, color = color.green, size = size.tiny)
plotshape(confirmedDown, title = "Confirmed cross down", style = shape.triangledown, location = location.top, color = color.red, size = size.tiny)
alertcondition(confirmedUp, "Qstick crossed above zero", "Qstick crossed above zero on a closed chart bar.")
alertcondition(confirmedDown, "Qstick crossed below zero", "Qstick crossed below zero on a closed chart bar.")- The line uses chart open and close. The Data Window exposes the raw body and gap for inspection.
- The SMA needs N non-missing body values before it appears. An absent early value is not zero momentum.
- The live line can move before close. Triangles and alert conditions wait for
barstate.isconfirmed. - Create a TradingView alert separately using the named up or down condition. An alert condition in the source does not create an active alert.
Confirmation follows TradingView's bar-state rules. Syntax validation checks code, not signal usefulness or trading returns.
Settings, sessions and failure modes
Length counts chart bars. With complete data, N = 1 returns the current body; a longer SMA dilutes a single body across more bars. Fourteen 5-minute bars cover 70 minutes of bar duration, while fourteen daily stock bars cover fourteen trading sessions. Breaks mean elapsed clock time can be longer. No length is established here as optimal.
Session boundaries change the question
On an intraday stock chart, including extended hours adds bars and changes which bodies fall inside a fixed-length window. A regular-session opening gap may instead appear across several extended-hours bodies. Compare regular and extended sessions as different input series, using TradingView's session definitions. This script does not reset its average at each new session.
On a continuously traded market, bar boundaries still matter. Combining small candles into a larger candle can turn intermediate moves into one net body. For many futures, the default regular session includes electronic trading hours; stock-session labels do not transfer directly. Keep feed, interval and session settings in any saved comparison.
- Near zero, small bodies or an outgoing large body can produce repeated crossings with little follow-through.
- One unusually large body can dominate the average until it leaves the SMA window.
- Raw Qstick values are not comparable across instruments with different price scales. Any price or volatility normalization needs its own formula and tests.
- Volume is absent, so the result cannot identify institutional activity or actual buyer-initiated order flow.
- Heikin Ashi and other non-standard charts can supply synthetic inputs. Use standard candles for market-price calculations.
Turn a Qstick idea into explicit rules
Pineify's Pine Script AI Coding Agent can help write or modify a script from a stated formula. For a trend-filter experiment, specify the filter separately from Qstick. The prompt below is a test specification, not a proven trading method.
Create a Pine v6 indicator using SMA(close - open, 14). Mark a long candidate only when Qstick crosses above zero on a closed chart bar and that bar closes above its 50-bar SMA of close. Show the unfiltered cross and the filtered candidate separately. Use chart data without future-bar references. Do not place orders.
If price moves above its SMA one bar after the Qstick crossing, this rule produces no candidate on that later bar. That is different from a state rule requiring only Qstick > 0 and price above its SMA. Check this timing distinction in the generated output.
Compare raw bodies, Qstick and each condition on several closed bars in TradingView. A later strategy version needs explicit exits, order timing, sizing, commissions and slippage. Freeze any chosen parameters before evaluating a separate period. The agent writes code; chart validation and strategy evaluation remain separate steps.
Customize Qstick with PineifyEducational examples, not investment advice. No return or signal-accuracy guarantee.
Qstick questions
Sources and related guides
Official documentation checked October 17, 2026. Numeric examples and algebraic comparisons are original calculations.