Williams %R
Williams %R (pronounced "Williams Percent R") measures where the current close sits within the high-low range of the last N periods — very similar to Stochastic, but on an inverted 0 to −100 scale. Readings from 0 to −20 = overbought, −80 to −100 = oversold. Developed by Larry Williams in 1973.
The formula
Williams %R = ((Highest High − Close) / (Highest High − Lowest Low)) × −100
Over a typical 14-period lookback. The scale runs from 0 (price closed at the period high) to −100 (price closed at the period low).
Williams %R vs Stochastic
Williams %R and Stochastic %K both measure the same thing — close relative to range — but:
| Feature | Williams %R | Stochastic %K |
|---|---|---|
| Scale | 0 to −100 | 0 to 100 |
| Overbought | 0 to −20 | 80 to 100 |
| Oversold | −80 to −100 | 0 to 20 |
| Smoothing | None | %D smoothing line |
| Speed | Faster, noisier | Slightly slower |
If you can use one, you can use the other. Williams %R is slightly more reactive because it doesn't include a smoothing line.
How to trade it
Overbought/oversold reversals. In ranging markets, %R hitting −20 (overbought) or −80 (oversold) often precedes reversal. Like all oscillators, this fails in strong trends — %R can peg at extremes for extended periods.
Divergence. Price makes a new high, %R doesn't = bearish divergence (momentum fading). Inverse for bullish divergence.
Confirmation. Some traders use %R to confirm trend-following entries. Long entries preferred when %R > −50 (above midpoint); short entries when < −50.
Williams %R in Pine Script (v6)
//@version=6
indicator("Williams %R + Alerts", overlay=false)
length = input.int(14, "Length")
obLevel = input.float(-20, "Overbought level")
osLevel = input.float(-80, "Oversold level")
willr = -100 * (ta.highest(high, length) - close) / (ta.highest(high, length) - ta.lowest(low, length))
plot(willr, color=color.orange, linewidth=2, title="%R")
hline(obLevel, "Overbought", color=color.red)
hline(-50, "Midpoint", color=color.gray)
hline(osLevel, "Oversold", color=color.green)
if ta.crossover(willr, osLevel)
alert("Williams %R exited oversold on " + syminfo.ticker, alert.freq_once_per_bar_close)
if ta.crossunder(willr, obLevel)
alert("Williams %R exited overbought on " + syminfo.ticker, alert.freq_once_per_bar_close)
Settings
14-period is the default and works on most timeframes. For scalping on 1-minute charts, you can tighten to 7. For swing trading on daily, extend to 21. Beyond that, the smoothing reduces usefulness.
Common mistakes
- Treating −20 and −80 as auto-trade signals. They're filters, not signals. Combine with structure or trend context.
- Using it in strong trends. Trend days peg %R at extremes. Fading every extreme reading in a trend will bleed you.
- Confusing the inverted scale. New users often expect overbought to be "high" and oversold to be "low," like RSI or Stochastic. On %R, overbought is closer to zero.
Frequently Asked Questions
Williams %R vs Stochastic — which should I use?
Either works — they measure the same thing with different scales. Stochastic has a smoothing %D line built in, Williams %R doesn't. If you prefer faster reactions, use %R. If you want a confirmation smoothing, use Stochastic. Most traders pick one and stick with it.
What's a good Williams %R setting?
The default 14-period is fine for most timeframes. Shorter (7) for scalping, longer (21) for swing trading. Unlike some indicators, %R's settings don't require tuning per market.
Can Williams %R be used as a standalone system?
Marginally. Like all oscillators, it works in ranging markets and fails in trends. Standalone win rates typically 45–55% depending on filters. Paired with a trend filter (200 EMA, ADX regime screen), it becomes part of a tradeable system.