Trading Strategy
Williams %R Strategy
A momentum oscillator strategy using Williams %R to identify overbought and oversold conditions with trend confirmation.
Mean Reversion Momentum
Williams %R (Williams Percent Range) is a momentum indicator that measures overbought and oversold levels. Unlike RSI or Stochastic, it uses a -100 to 0 scale where values below -80 indicate oversold conditions and values above -20 indicate overbought conditions. Combined with a 200 EMA trend filter, this strategy provides reliable mean reversion signals.
Momentum Type
4h Chart Timeframe
Intermediate Complexity
Williams %R + EMA + ATR Indicators
Signal Logic
Long (Buy)
Williams %R crosses above oversold level (-80), price is above 200 EMA.
Short (Sell)
Williams %R crosses below overbought level (-20), price is below 200 EMA.
Implementation
//@version=6
strategy("Williams %R Strategy", overlay=true, initial_capital=1000000, default_qty_type=strategy.percent_of_equity, default_qty_value=100)
// ==========================================
// 🔹 INPUTS
// ==========================================
// Group: Williams %R Settings
grp_wr = "Williams %R Settings"
wr_len = input.int(14, "Williams %R Period", minval=1, group=grp_wr)
wr_oversold = input.int(-80, "Oversold Level", group=grp_wr)
wr_overbought = input.int(-20, "Overbought Level", group=grp_wr)
// Group: Trend Filter
grp_trend = "Trend Filter"
use_trend = input.bool(true, "Use Trend Filter (EMA 200)", group=grp_trend)
ema_len = input.int(200, "Trend EMA Length", minval=1, group=grp_trend)
// Group: Risk Management
grp_risk = "Risk Management"
atr_len = input.int(14, "ATR Length", minval=1, group=grp_risk)
sl_mult = input.float(2.0, "Stop Loss (ATR Multiplier)", step=0.1, group=grp_risk)
tp_ratio = input.float(2.0, "Risk:Reward Ratio", step=0.1, group=grp_risk)
// ==========================================
// 🔹 CALCULATIONS
// ==========================================
// Williams %R Indicator
wr_val = ta.wpr(wr_len)
// Trend EMA
ema_val = ta.ema(close, ema_len)
// ATR for risk management
atr_val = ta.atr(atr_len)
// Trend conditions
trend_up = use_trend ? close > ema_val : true
trend_down = use_trend ? close < ema_val : true
// ==========================================
// 🔹 STRATEGY LOGIC
// ==========================================
// Long Entry: %R crosses above oversold level (bullish reversal)
long_signal = ta.crossover(wr_val, wr_oversold) and trend_up
// Short Entry: %R crosses below overbought level (bearish reversal)
short_signal = ta.crossunder(wr_val, wr_overbought) and trend_down
// ==========================================
// 🔹 EXECUTION & RISK MANAGEMENT
// ==========================================
if long_signal
strategy.entry("Long", strategy.long, comment="L | %R Bull")
if short_signal
strategy.entry("Short", strategy.short, comment="S | %R Bear")
// Risk management with ATR
if strategy.position_size > 0
stop_level = strategy.position_avg_price - (atr_val * sl_mult)
profit_level = strategy.position_avg_price + (atr_val * sl_mult * tp_ratio)
strategy.exit("Exit Long", "Long", stop=stop_level, limit=profit_level, comment_loss="SL", comment_profit="TP")
if strategy.position_size < 0
stop_level = strategy.position_avg_price + (atr_val * sl_mult)
profit_level = strategy.position_avg_price - (atr_val * sl_mult * tp_ratio)
strategy.exit("Exit Short", "Short", stop=stop_level, limit=profit_level, comment_loss="SL", comment_profit="TP")
// ==========================================
// 🔹 VISUALS
// ==========================================
// Plot Trend EMA
plot(use_trend ? ema_val : na, "Trend EMA", color=color.new(color.orange, 0), linewidth=2)
// Plot Williams %R Reference Levels
plot(wr_overbought, "Overbought", color=color.new(color.red, 70), linestyle=plot.linestyle_dashed)
plot(wr_oversold, "Oversold", color=color.new(color.green, 70), linestyle=plot.linestyle_dashed)
plot(-50, "Center Line", color=color.new(color.gray, 80), linestyle=plot.linestyle_dashed)
// Plot Signals on price chart
plotshape(long_signal, title="Long Signal", location=location.belowbar, color=color.green, style=shape.labelup, text="BUY", textcolor=color.white)
plotshape(short_signal, title="Short Signal", location=location.abovebar, color=color.red, style=shape.labeldown, text="SELL", textcolor=color.white)
// Background color for overbought/oversold zones
overbought_zone = wr_val > wr_overbought
oversold_zone = wr_val < wr_oversold
bgcolor(overbought_zone ? color.new(color.red, 95) : oversold_zone ? color.new(color.green, 95) : na)