Williams %R
I. What is Williams %R
Williams %R (also known as %R or W%R) is a momentum oscillator that measures the position of the current closing price relative to the price range over a given period. It is very similar to Stochastic %K, but %R expresses the “distance from the top of the range,” so its values are negative (-100 to 0), using inverse logic.
Historical Background
Williams %R was invented by the famous American trader Larry Williams. Larry Williams won the 1987 World Cup Trading Championship with a record-breaking return of 11,376%. The %R indicator became popular among short-term traders due to its simple calculation and direct signals.
Indicator Classification
- Type: Oscillator, displayed in a separate panel
- Category: Momentum
- Default Parameters: Period
- Value Range: -100 to 0
Williams %R and Fast Stochastic %K are mathematical mirror images: When %K = 80 (overbought zone), %R = -20; when %K = 20 (oversold zone), %R = -80.
II. Mathematical Principles and Calculation
Core Formula
Where:
- = current closing price
- = highest high over the past periods
- = lowest low over the past periods
- = lookback period (default 14)
Equivalent Expression
It can be seen that .
Step-by-Step Calculation Logic
- Determine lookback period (default 14)
- Calculate range extremes: Find the highest high and lowest low over the past periods
- Calculate distance from top:
- Divide by range width:
- Multiply by -100: Map the result to the -100 to 0 range
Value Interpretation
| %R Value | Meaning |
|---|---|
| 0 | Closing price equals the range high |
| -50 | Closing price is at the midpoint of the range |
| -100 | Closing price equals the range low |
Larry Williams chose the negative range (-100 to 0) to visually represent the “distance from the top” on charts. The closer %R is to 0, the closer the price is to the range top (overbought); the closer to -100, the closer the price is to the range bottom (oversold). This design, while inverted compared to Stochastic, offers its own visual advantages.
III. Python Implementation
import numpy as np
import pandas as pd
def williams_r(high: pd.Series,
low: pd.Series,
close: pd.Series,
period: int = 14) -> pd.Series:
"""
Calculate Williams %R
Parameters
----------
high : pd.Series
High price series
low : pd.Series
Low price series
close : pd.Series
Close price series
period : int
Lookback period, default 14
Returns
-------
pd.Series
Williams %R values (-100 to 0)
"""
highest_high = high.rolling(window=period, min_periods=period).max()
lowest_low = low.rolling(window=period, min_periods=period).min()
wr = (highest_high - close) / (highest_high - lowest_low) * (-100)
return wr
# ========== Usage Example ==========
if __name__ == "__main__":
np.random.seed(42)
dates = pd.date_range("2024-01-01", periods=120, freq="D")
base = 100 + np.cumsum(np.random.randn(120) * 1.0)
df = pd.DataFrame({
"date": dates,
"open": base + np.random.randn(120) * 0.3,
"high": base + np.abs(np.random.randn(120) * 0.8),
"low": base - np.abs(np.random.randn(120) * 0.8),
"close": base,
"volume": np.random.randint(1000, 10000, size=120),
})
df.set_index("date", inplace=True)
# Calculate Williams %R
df["WR_14"] = williams_r(df["high"], df["low"], df["close"], period=14)
print("=== Williams %R Results (last 15 rows) ===")
print(df[["close", "WR_14"]].tail(15).to_string())
# Overbought/Oversold signals
df["signal"] = np.where(
df["WR_14"] > -20, -1, # Overbought (near 0)
np.where(df["WR_14"] < -80, 1, 0) # Oversold (near -100)
)
print("\n=== Overbought Signals (%R > -20) ===")
overbought = df[df["signal"] == -1]
print(overbought[["close", "WR_14"]].head(10).to_string())
print("\n=== Oversold Signals (%R < -80) ===")
oversold = df[df["signal"] == 1]
print(oversold[["close", "WR_14"]].head(10).to_string())
IV. Problems the Indicator Solves
1. Overbought / Oversold Detection
| Zone | Condition | Meaning |
|---|---|---|
| Overbought | %R > -20 | Price near range top, pullback likely |
| Oversold | %R < -80 | Price near range bottom, bounce likely |
| Neutral | -80 <= %R <= -20 | No extreme signal |
2. Trend Confirmation
- %R operating between -50 and 0 — bullish trend
- %R operating between -100 and -50 — bearish trend
- %R crossing back and forth around -50 — oscillating, no trend
3. Divergence Signals
- Bearish Divergence: Price makes a new high, %R fails to reach a higher level — upward momentum exhausted
- Bullish Divergence: Price makes a new low, %R fails to reach a lower level — downward momentum exhausted
4. Failure Swing
Similar to RSI:
- %R pulls back from overbought zone, rallies but fails to re-enter overbought — short signal
- %R bounces from oversold zone, declines but fails to re-enter oversold — long signal
%R has no built-in smoothing mechanism, so signal fluctuations are significant. In practice, many traders apply an additional SMA(3) or EMA(3) smoothing to %R to reduce noise.
V. Advantages, Disadvantages, and Use Cases
Advantages
| Advantage | Description |
|---|---|
| Extremely simple | Simple formula, fast computation |
| Highly responsive | No built-in smoothing, directly reflects price position within range |
| Intuitive thresholds | -20 and -80 boundaries are clear |
| Complements Stochastic | Provides a reverse perspective, convenient for cross-validation |
Disadvantages
| Disadvantage | Description |
|---|---|
| High noise | No smoothing leads to frequent false signals |
| Saturates in trends | Stays in overbought/oversold zones during strong trends |
| Negative value intuition | -100 to 0 inverse logic is less intuitive than 0-100 |
| Needs confirmation | Not recommended as a standalone trading decision basis |
Use Cases
- Short-term trading: Suited for quick in-and-out trading styles
- Range-bound markets: Overbought/oversold signals work well within clear support/resistance zones
- Alternative to Stochastic: When a more raw, sensitive signal is needed
Comparison with Related Indicators
| Comparison | Williams %R | Stochastic | RSI |
|---|---|---|---|
| Value Range | -100 to 0 | 0-100 | 0-100 |
| Smoothing | None | Dual SMA smoothing | Wilder Smoothing |
| Sensitivity | Very high | High | Medium |
| Noise | High | Medium | Low |
| Math Relationship | %K - 100 | Independent | Independent |
- Add smoothing: In practice, apply a 3-5 period SMA smoothing to %R before use.
- Combine with trend indicators: Use moving averages or ADX to determine trend direction, then use %R to find entries.
- Watch for exits from extreme zones: The moment %R crosses above -80 from oversold or below -20 from overbought is more meaningful than staying in extreme territory.
- Cross-validate with Stochastic: Signals from both should agree; if they diverge, stay on the sidelines.