Relative Strength: What It Does and Does Not Mean
Two analysts look at the same stock on the same day. One says it has been strong for months. The other says it has been weak all year. Both are right, and neither is being careless: they are measuring against different things over different windows, and “relative strength” is a family of measurements rather than a single number.
By the end of this lesson you should be able to say, for any relative strength figure you meet, three things: what the numerator is, what the denominator is, and over what window it was measured. If you cannot answer all three, the number is not yet a measurement.
Two unrelated things share the name
Section titled “Two unrelated things share the name”AmiBroker’s RSI() is documented as the relative strength index. It compares a
symbol to its own recent history — the size of its up moves against the size of its
down moves. It never looks at another symbol. It is a single-symbol, time-series
indicator, and it has nothing to do with the subject of this part.
What this part is about is comparative relative strength: one symbol measured against
another symbol, or against an index, on the same bars. AmiBroker keeps that under a
separate function, RelStrength(), filed in the reference under “Referencing other
symbol data”. The two share four letters and no concept.
Relative strength as a ratio
Section titled “Relative strength as a ratio”The oldest form is a plain ratio: divide one price series by another, bar by bar.
Fragment — not a complete formula
Ratio = Close / Foreign( "^GSPC", "C" );That is one number per bar, like every other AFL expression. Here is what it looks like on five bars where the stock rises 20 per cent and the index rises 10 per cent:
A relative strength ratio is computed bar by bar
| Bar | 1 | 2 | 3 | 4 | 5 |
|---|---|---|---|---|---|
Close (stock) | 50.0 | 51.0 | 53.0 | 54.0 | 60.0 |
Foreign index close | 1000 | 1010 | 1030 | 1040 | 1100 |
Ratio | 0.0500 | 0.0505 | 0.0515 | 0.0519 | 0.0545 |
The important property is in the caption. A ratio of 0.05 means nothing on its own — it
would be 50 if the index were quoted in thousands, or 0.00005 if the stock had done a
1-for-1000 split. What is readable is the change in the ratio: a rising line says the
numerator outpaced the denominator over that stretch; a falling line says the reverse.
Two consequences follow immediately, and both catch people out.
A rising ratio does not mean a rising price. If the stock falls 10 per cent while the index falls 25 per cent, the ratio rises. “Outperforming” and “going up” are different statements, and a screen built on a rising ratio will happily hand you a list of things that are all falling.
A ratio line has no fixed zero. Comparing the ratio’s level across two symbols is meaningless, because each pair has its own arbitrary scale. This is why ratio charts are usually rebased — set to 100 at a chosen start date — before two of them are put side by side, and why the choice of start date then quietly becomes part of the answer. Part 15 takes rebasing and its start-date sensitivity apart in detail.
AmiBroker’s own function
Section titled “AmiBroker’s own function”RelStrength( "tickername", fixup = 1 ) returns an array described on its official page
as the comparative relative strength of the currently selected security against
tickername. The page documents the arguments and the hole-filling behaviour, but it
does not print the arithmetic. If you need to know exactly which number you are looking
at — and for anything you intend to rank on, you do — compute the ratio yourself so that
the definition is in your formula rather than in a footnote you cannot read.
Choosing the denominator changes the question
Section titled “Choosing the denominator changes the question”The denominator is not a technicality. It decides what question you are asking.
Against a broad benchmark, you are asking whether the symbol beat the market. That suits a decision about whether to hold this instead of an index fund, and it is the comparison most published “relative strength” numbers use.
Against a sector, you are asking whether the symbol beat its peers. This separates two effects that a market comparison merges: a mining stock in a year when mining did well may look excellent against the broad market and unremarkable against other miners. Which of those you want depends entirely on the decision in front of you. Note that “the sector” has to be represented by something concrete — a sector index, a sector ETF, or a composite you build yourself — and each of those has its own defects, which Part 15 and Part 16 cover.
Against a single peer, you are asking a pair question, which is the basis of spread and pairs research. It is the most specific and the least stable: two-symbol relationships come apart without warning.
Momentum ranking measures something else again
Section titled “Momentum ranking measures something else again”The other common meaning of “relative strength” — the one that drives most published ranking systems — is not a ratio line at all. It is a return over a fixed window, computed for every symbol, and then compared across symbols on the same bar. Sometimes the benchmark’s return over the same window is subtracted first, giving an excess return.
Fragment — not a complete formula
ExcessReturn = ROC( Close, 126 ) - ROC( BenchClose, 126 );The distinction matters because the two answer different questions. The ratio line is a path: it shows when the symbol was gaining ground and when it was losing it. The window return is a single summary of the whole window that says nothing about the path taken to get there. A stock that rose steadily for six months and one that collapsed and then doubled can have identical six-month returns and completely different ratio lines.
Why “strongest” is a statement about a window
Section titled “Why “strongest” is a statement about a window”This is the point worth taking away from the lesson, and it is easier to see than to argue about.
Build a chart pane that measures one symbol’s excess return over a benchmark across three different lookback windows at the same time, so you can watch the three disagree.
Complete formula
Section titled “Complete formula”Complete runnable AFL
// relative-strength-lookbacks.afl// Part 13 - Relative Strength: What It Does and Does Not Mean//// Measures one symbol's relative strength against one benchmark over three// different lookback windows at once, so that the disagreement between the// windows is visible instead of assumed.//// Assumptions declared up front:// - Daily bars, and a benchmark symbol that exists in this database. The// formula checks that with the documented return value of SetForeign// rather than guessing, because a missing benchmark produces a chart that// looks fine and means nothing.// - Switching to the benchmark with SetForeign uses the documented default// fixup = 1: benchmark days that are missing are filled from the previous// close and carry zero volume. Days the CURRENT symbol did not trade do// not exist for either series.// - The first LongLookback bars are warm-up and carry no information.// - Nothing here is a signal. It is a description of past relative price.
_SECTION_BEGIN( "Relative strength lookbacks" );
BenchSymbol = ParamStr( "Benchmark symbol", "^GSPC" );ShortLookback = Param( "Short lookback (bars)", 21, 5, 63, 1 );MidLookback = Param( "Medium lookback (bars)", 63, 20, 150, 1 );LongLookback = Param( "Long lookback (bars)", 252, 60, 500, 1 );
// SetForeign returns 1 when the ticker exists and 0 when it does not, and on// failure it leaves the price arrays untouched. That documented return value// is the only reliable existence test available to us.BenchExists = SetForeign( BenchSymbol );BenchClose = Close; // while the swap is in force, Close IS the benchmarkRestorePriceArrays();
// Excess return over each window: how far the symbol's own percentage change// over exactly those bars exceeded the benchmark's, in percentage points.// Subtracting two rates of change is not identical to the rate of change of// the ratio, but it is easier to read and far easier to check by hand.ShortExcess = ROC( Close, ShortLookback ) - ROC( BenchClose, ShortLookback );MidExcess = ROC( Close, MidLookback ) - ROC( BenchClose, MidLookback );LongExcess = ROC( Close, LongLookback ) - ROC( BenchClose, LongLookback );
// If the benchmark is missing, BenchClose is this symbol's own close, so every// excess reading collapses to zero. Blanking the plots makes that obvious.ShortExcess = IIf( BenchExists, ShortExcess, Null );MidExcess = IIf( BenchExists, MidExcess, Null );LongExcess = IIf( BenchExists, LongExcess, Null );
Plot( ShortExcess, "Excess % over " + ShortLookback + " bars", colorBlue, styleLine );Plot( MidExcess, "Excess % over " + MidLookback + " bars", colorOrange, styleLine );Plot( LongExcess, "Excess % over " + LongLookback + " bars", colorGreen, styleLine | styleThick );
// Zero is the only level on this pane with a meaning: above it the symbol// outpaced the benchmark over that window, below it the benchmark won.PlotGrid( 0, colorGrey40 );
Title = Name() + " relative to " + BenchSymbol + " " + WriteIf( BenchExists, "", "BENCHMARK NOT FOUND - nothing on this pane means anything. " ) + "excess over " + NumToStr( ShortLookback, 1.0 ) + "/" + NumToStr( MidLookback, 1.0 ) + "/" + NumToStr( LongLookback, 1.0 ) + " bars: " + WriteVal( ShortExcess, 1.1 ) + "% " + WriteVal( MidExcess, 1.1 ) + "% " + WriteVal( LongExcess, 1.1 ) + "%";
_SECTION_END();How it works
Section titled “How it works”The formula has three logical sections. The first reads the benchmark. Rather than
guessing whether the benchmark symbol exists, it uses SetForeign(), whose official page
states that it returns True when the ticker exists and False otherwise, and that on
failure the price arrays are left unchanged. That gives an exact existence test and, in
the same call, swaps every price array over to the benchmark so the plain identifier
Close refers to the benchmark’s closes until RestorePriceArrays() puts things back.
The second section computes three excess returns, one per lookback, by subtracting the
benchmark’s rate of change from the symbol’s over exactly the same number of bars. The
third blanks all three series with Null when the benchmark was not found, because a
missing benchmark would otherwise leave BenchClose holding this symbol’s own closes and
every excess reading would collapse to a tidy, meaningless zero.
Key functions
Section titled “Key functions”SetForeign( ticker, fixup = True, tradeprices = False )— swaps the built-in price arrays to another symbol. Note that the second argument isfixup, not a data field:Foreign()takes the field second,SetForeign()does not, and mixing them up is a silent logic error rather than a syntax error.RestorePriceArrays( tradeprices = False )— puts the original arrays back. It is mandatory after everySetForeign(), and itstradepricesargument must match.ROC( ARRAY, periods = 12, absmode = False )— percentage rate of change overperiodsbars.PlotGrid( level, color )— draws the horizontal line at zero, which is the only level on this pane that means anything.
Expected result
Section titled “Expected result”Three lines oscillating around zero and a grid line at zero. On a liquid share with several years of daily history, the short line will cross zero many times a year, the medium line rather less, and the long line may spend a year at a time on one side. That picture is the lesson: at most bars the three lines are not on the same side of zero.
Test it
Section titled “Test it”Pick a bar where the short line is well above zero and the long line well below it. Read the symbol’s own close on that bar and the close 21 bars earlier, and do the percentage change by hand. Do the same for the benchmark, subtract, and check it matches the blue line’s value in the chart title. Then repeat with 252 bars. Two arithmetic checks are enough to convince you the numbers are what they claim to be — and that the disagreement is real rather than a plotting artefact.
Common errors
Section titled “Common errors”- A flat line at exactly zero. The benchmark symbol was not found, and the title says so. Check the ticker’s spelling against Symbol → Information.
- Wild values at the left edge of the chart. The first bars are warm-up;
ROC()over 252 bars is undefined until there are 252 prior bars. - Every symbol looks strong. Check what the benchmark actually is. A benchmark that is itself a weak sector index will make almost everything look good.
- Values that jump on one date across many symbols. That is usually a data problem in the benchmark, not a market event. Chart the benchmark on its own.
Extension
Section titled “Extension”Add a fourth line: the excess return over the shortest window, but computed against a sector proxy rather than the index. Watching a symbol be strong against its sector and weak against the market — or the reverse — is the most useful version of this picture.
What relative strength does not tell you
Section titled “What relative strength does not tell you”Beyond that, a relative strength reading is silent on several things that decide whether acting on it is possible at all:
- Liquidity. The strongest name in a universe is often the smallest and thinnest one. Nothing in a ratio or a return knows about spread, depth or the size you could trade.
- Risk. Two symbols with identical excess returns can have had entirely different drawdowns getting there. Rank on return alone and you rank volatility in through the back door.
- The reason. A takeover bid, a one-off contract award and a genuine change in trading fortunes look the same in a rate of change.
- The universe. A ranking computed over today’s index members tells you about a set chosen with hindsight. Part 30 has the full account of why that matters.
- What happens next. The measurement is entirely of the past. It has no forward component in it at all.
Relative strength is not one thing. It is a ratio, or an excess return, measured against a denominator you chose, over a window you chose. The ratio’s level is arbitrary and only its change is readable; the window return is a summary that discards the path. Changing the benchmark changes the question, and changing the window changes the answer — often completely. The next lesson takes the second half of that sentence seriously and asks what happens when you stop testing symbols one at a time and start putting them in order.
Check your understanding
Sources for this lesson
6 verified · checked 2026-08-31
- 01AFL Function Reference - RelStrengthamibroker.com/guide/afl/relstrength.html2026-08-31
- 02AFL Function Reference - RSIamibroker.com/guide/afl/rsi.html2026-08-31
- 03AFL Function Reference - SetForeignamibroker.com/guide/afl/setforeign.html2026-08-31
- 04AFL Function Reference - ROCamibroker.com/guide/afl/roc.html2026-08-31
- 05AmiBroker User's Guide - Categories window§ Base indexesamibroker.com/guide/w_categories.html2026-08-31
- 06AmiBroker User's Guide - Ranking functionalityamibroker.com/guide/h_ranking.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.