◆ New — Strategy Validator, Code Fixer & Prop Compliance Checker are live. Try one free →
Home / Indicators / Williams %R
Momentum indicator

Williams %R

A momentum oscillator that shows where the latest close sits within the recent high-low range.

Illustrative diagram — not live market data.

What it is

Williams %R (Williams Percent Range), developed by Larry Williams, is a momentum oscillator that measures where the current close falls relative to the highest high and lowest low over a chosen lookback period (commonly 14 bars). It moves on an inverted scale from 0 down to -100: readings near 0 mean the close is at the top of the recent range, and readings near -100 mean it is at the bottom. It is closely related to the Fast Stochastic oscillator, differing mainly in its inverted scale. Like all indicators, it describes past price behavior and is not predictive; trading always carries risk of loss.

How it works

For each bar, the indicator looks back over a set number of periods and finds the highest high and lowest low in that window. It then measures how far the most recent close is from the top of that range, expressed as a percentage of the full range. If the close equals the highest high, the value is 0; if it equals the lowest low, the value is -100; a close in the middle of the range gives about -50. The formula is: %R = (Highest High - Close) / (Highest High - Lowest Low) x -100. Because the scale is flipped, the line sits near the top of the panel during strength and near the bottom during weakness.

How traders read it

Common settings

Default length is 14 periods. Common reference lines are -20 (upper) and -80 (lower); some traders use -10/-90 for stricter extremes. Shorter lengths (e.g., 7-10) react faster but are noisier; longer lengths (e.g., 21-28) are smoother but lag more.

Strengths

Pitfalls to watch

Pine v6 example

//@version=6
indicator("Williams %R", overlay = false)

length = input.int(14, "Length", minval = 1)
percentR = ta.wpr(length)

plot(percentR, "Williams %R", color = color.blue)
hline(-20, "Overbought", color = color.gray, linestyle = hline.style_dashed)
hline(-80, "Oversold", color = color.gray, linestyle = hline.style_dashed)

Pro tip: Because %R spends a lot of time at its extremes, many traders use it for context alongside trend tools rather than as a standalone trigger - for example, only noting an 'oversold' reading when the broader trend is already up. Treat it as one input among several, and remember no indicator is predictive and all trading carries risk of loss.

Built an indicator from this? Run it through the Validator to catch look-ahead bias and repainting, or convert a strategy to Pine Script.

Educational only — not financial advice, not a recommendation to trade. No indicator is predictive; trading involves substantial risk of loss.

Catch the bug that compiles.Run auditGet Pro