RSI and Rate of Change
RSI is the most widely used and most widely misread indicator in technical analysis. The misreading is not a matter of opinion — it follows from the published formula, which AmiBroker prints in full on its own reference page. This lesson works through that formula until the behaviour everyone complains about becomes obviously inevitable, then does the same for the simpler indicator that sits next to it, rate of change.
What RSI measures
Section titled “What RSI measures”AmiBroker publishes the internal algorithm. Here it is as structured English:
Pseudocode — not valid AFL
P = 0 // smoothed average up-moveN = 0 // smoothed average down-move
for each bar i after the first: diff = Close[i] - Close[i-1] W = diff if diff > 0, else 0 S = -diff if diff < 0, else 0 P = ( (period - 1) * P + W ) / period N = ( (period - 1) * N + S ) / period if i >= period: result[i] = 100 * P / ( P + N )Read it as three statements.
One: RSI sees only the differences between consecutive closes. Not the highs, not the lows, not the ranges, not the gaps, not the volume. A day that opened limit-down, traded across a 9 per cent range and closed 0.1 per cent up is, to RSI, a small up-move.
Two: the smoothing is Wilder’s, and it is recursive. Each new P is a blend of the
previous P and today’s up-move, weighted (period-1) to 1. That is not a simple average of
the last fourteen gains, and it is not the standard 2/(n+1) exponential average either. This
is why RSI values from two platforms can differ slightly, and it is why P and N never
fully forget: every bar the indicator has seen still contributes a decaying share.
Three: the result is a ratio of a non-negative number to a sum of non-negative numbers, so it is confined to the range 0 to 100 by arithmetic, not by clipping.
Two consequences worth deriving yourself
Section titled “Two consequences worth deriving yourself”Unchanged closes do not move RSI at all. If today’s close equals yesterday’s, both W and
S are zero, so both P and N are multiplied by (period-1)/period. The ratio
P / ( P + N ) is unchanged. A week of identical closes leaves RSI exactly where it was —
which matters on illiquid instruments where flat closes are common, because the indicator
looks stable when in fact nothing is being measured.
A persistent advance drives RSI towards 100 mechanically. Suppose ten consecutive up
closes. On each of them S is zero, so N is multiplied by 13/14 each time. After ten such
bars N has shrunk to about 48 per cent of where it started, and after twenty to about 23 per
cent, while P is being topped up on every bar. 100 * P / ( P + N ) climbs towards 100
because the denominator is collapsing.
What a run of up closes does to the ratio
| Bar | start | +5 bars | +10 bars | +15 bars | +20 bars |
|---|---|---|---|---|---|
N, as a share of its starting value | 1.00 | 0.69 | 0.48 | 0.33 | 0.23 |
RSI if P holds steady | 50.0 | 59.2 | 67.7 | 75.3 | 81.5 |
That table is the entire answer to “why does RSI stay above 70 for months in a strong trend”. It is not the indicator failing to warn you. A high reading is the signature of a market that has been going one way with few interruptions, which is the definition of a trend.
What RSI does not measure
Section titled “What RSI does not measure”It does not measure how far price has moved. A stock that has climbed 3 per cent in fourteen sessions without a single down day will read higher than one that has climbed 30 per cent in fourteen sessions with five sharp pullbacks. RSI measures the consistency of direction, weighted by the size of the moves — a different thing from the size of the move itself.
It does not measure value, cheapness, or extension from any average. It has no idea where price is relative to anything.
And its level is not comparable in any absolute sense between instruments with different character. A steady index and a speculative small-cap will spend their time in different parts of the 0-to-100 range as a matter of habit.
Rate of change: the two-point alternative
Section titled “Rate of change: the two-point alternative”Where RSI is a smoothed ratio, ROC is a single subtraction. AmiBroker publishes both forms:
Fragment — not a complete formula
// The documented definition of ROC, for reference — not something to type.// absmode = False (the default):100 * ( array - Ref( array, -periods ) ) / Ref( array, -periods )// absmode = True:100 * ( array - Ref( array, -periods ) ) / abs( Ref( array, -periods ) )Four documented details, each of which catches people:
The default period is 12, not 14 and not 10. ROC( Close ) is a twelve-bar rate of change.
It is the one momentum function in this family whose default is not 14.
The result is already a percentage. It is multiplied by 100 inside the function. Do not multiply again.
The array argument is required and comes first. Unlike RSI, MFI, CCI and ADX,
ROC does not default to the close — ROC( 12 ) is an error.
absmode exists for arrays that can go negative. With the default False the denominator
is the signed earlier value, so applying ROC to an oscillator, a spread or the MACD line
flips the sign of the result whenever that earlier value was negative.
The behavioural difference from RSI matters more than the arithmetic. Because ROC compares
exactly two bars and ignores everything in between, it is jumpy, and it has a drop-out
artefact of its own: on the bar where a large move falls out of the comparison window, the
reading changes sharply even though today did nothing. If you see a momentum reading collapse
on a quiet day, look twelve bars back before looking for news.
ROC has one real advantage over almost everything else in this part: it is a percentage, so
it is directly comparable between instruments. That property is what makes it the natural
building block for relative strength ranking in Part 13.
Displaying them in AmiBroker
Section titled “Displaying them in AmiBroker”RSI belongs in its own pane. Drop it there from Window -> Charts by double-clicking. If you
drag it onto the price pane instead you get a flat line along the bottom of the chart, because
the pane is scaled for prices; the documented fix is the styleOwnScale style from
Parameters -> Style, though a separate pane is usually what you actually wanted.
For the horizontal lines, the Parameters window’s Axes & Grid tab offers a fixed set of
popular grid levels including 30/70, 20/80 and 10/90, which covers the usual
choices without any code. From a formula, PlotGrid is the documented way to draw a constant
level — AmiBroker’s own page recommends it over plotting a constant array, for performance:
Fragment — not a complete formula
Momentum = RSI( 14 );
Plot( Momentum, "RSI(14)", colorBlue, styleLine | styleThick );PlotGrid( 70, colorRed, 9, 1, True );PlotGrid( 30, colorGreen, 9, 1, True );PlotGrid( 50, colorGrey40, 8, 1, False );Draw the 50 line as well as the 70 and 30 lines. It is the level at which smoothed up-moves and down-moves are equal, which is a more meaningful reference point than either of the others, and almost nobody plots it.
ROC is unbounded, so it also needs its own pane, with a grid line at zero:
Fragment — not a complete formula
ChangePct = ROC( Close, 12 ); // already a percentage
Plot( ChangePct, "ROC(Close, 12) %", colorBlue, styleLine | styleThick );PlotGrid( 0, colorBlack, 9, 1, False );Writing them in AFL
Section titled “Writing them in AFL”Fragment — not a complete formula
Momentum = RSI( 14 ); // no input array — RSI reads the built-in CloseChangePct = ROC( Close, 12 ); // ROC requires the array, and it comes firstExtended = Momentum > 70; // a state, true on every qualifying barJustCrossed = Cross( Momentum, 70 ); // an event, true on one barTwo naming traps. rsi is a function name, so rsi = RSI( 14 ); does not compile — AmiBroker’s
language reference states that user identifiers cannot duplicate function names. And if you
need RSI of something other than the close, the documented function is RSIa( array, periods = 14 ),
with the array first: RSIa( High, 12 ) is AmiBroker’s own example. Searching the on-line
function index for it finds nothing, because it is documented as a second syntax on the RSI
page rather than as its own entry. It is real; it is just filed oddly, exactly like CCIa on
the CCI page.
The misuse this course keeps returning to
Section titled “The misuse this course keeps returning to”Here is the claim, stated the way it is usually stated:
RSI above 70 means the market is overbought. Sell.
Everything in this lesson bears on it. RSI above 70 means the smoothed average up-move has been comfortably larger than the smoothed average down-move over a recursive window — which is to say, the market has been rising steadily. The advice therefore reduces to “sell markets that have been rising steadily”, which may be good advice or terrible advice, but is certainly not something the indicator discovered.
Notice also what the claim leaves unspecified: which market, over what period, sold at what price, held for how long, compared against what alternative. Without those, it cannot be wrong, and a statement that cannot be wrong is not knowledge.
The final lesson of this part takes that sentence, turns it into something that can be wrong, tests it on your own data, and reads the result honestly — including a frank list of what the test settles and what it does not.
RSI is 100 * P / ( P + N ), where P and N are Wilder-smoothed averages of up-moves and
down-moves of the close. It sees only close-to-close differences, it is bounded by
construction, it is Null for bars 0 to periods - 1, and it is unaffected by unchanged
closes. A persistent one-way move collapses the denominator and drives the reading towards its
ceiling, so a high value is the signature of a trend rather than a warning about one. ROC is
the two-point alternative: already a percentage, default period 12, array argument required
and first, with an absmode argument for inputs that can go negative. Both are momentum
measurements. Neither is an instruction.
Check your understanding
Sources for this lesson
6 verified · checked 2026-08-31
- 01AFL Function Reference — RSI§ Internal implementation comment by Tomasz Janeczkoamibroker.com/guide/afl/rsi.html2026-08-31
- 02AFL Function Reference — ROCamibroker.com/guide/afl/roc.html2026-08-31
- 03AFL Function Reference — Refamibroker.com/guide/afl/ref.html2026-08-31
- 04AFL Function Reference — PlotGridamibroker.com/guide/afl/plotgrid.html2026-08-31
- 05AmiBroker User's Guide — Parameters window§ Grid levelsamibroker.com/guide/w_param.html2026-08-31
- 06AmiBroker User's Guide — AFL language reference§ Identifiersamibroker.com/guide/a_language.html2026-08-31
Every technical claim on this page was checked against the official AmiBroker documentation on the date shown. Where the course disagrees with folklore, the source is how you can tell which one to trust.