WilliamsClose — Williams Close
A Williams %R variant computed on closes: how far the current close sits below the highest close of the window, on a −100–0 scale.
WilliamsClose is the identifier a strategy writes; Williams Close is the label the chart’s indicator picker shows. Single value — .value is the only accessor.
Signature
WilliamsClose(period, on=<source>)| Argument | Type | Required | Notes |
|---|---|---|---|
period |
int Param or literal | Yes | Lookback window. Default 14, bounds 5–100. |
on= |
symbol, OHLCV field, or indicator | No | Source. Defaults to the trade symbol’s close. |
Formula
Over the last N values of the source:
$$ \text{WilliamsClose} = \frac{\max - \text{close}_t}{\max(\max - \min,\ 0.0001)} \times -100 $$
0 means the close is the highest of the window (overbought), -100 means it is the lowest (oversold), -50 is mid-range. The denominator is floored at a small epsilon so a flat window cannot divide by zero.
Warmup
period bars. Before the window fills, the indicator returns -50 — the neutral midpoint of its own scale, not 0. A strategy never observes it (execute() waits until every indicator is ready); it is what the chart plots on the leading bars.
Reading the value
wr.value # -100..0wr.value_at(1)wr < -80 # oversoldwr > -20 # overboughtwr.crossed_above(-80) # the bar it leaves oversoldExample
class WilliamsReversion(Strategy): """Buy deep oversold readings, exit as price returns to the top of the range.""" period = Param(14, min=5, max=100) trade = Symbol() sizing = FixedCapital()
def execute(self): wr = WilliamsClose(self.period, on=self.trade) self.stop_loss(3.0)
if wr.crossed_above(-80) and self.trade.is_flat: self.buy(self.trade, reason=f"Leaving oversold ({wr.value:.0f})")
if wr.value > -20 and self.trade.is_long: self.sell(self.trade, self.trade.position, reason="Back at the range high")Notes
- Every threshold is negative.
wr.value > 80can never be true — the scale tops out at0. Overbought is> -20; oversold is< -80. This is the single most common mistake with this indicator. - A perfectly flat window reads
0— the overbought end — because the numerator collapses to zero while the epsilon-floored denominator keeps the division finite. Treat a zero-range window as no signal, not as a top. - This is
StochasticCloseinverted and shifted:WilliamsClose = StochasticClose − 100. Pick whichever scale you find easier to read; they carry the same information. - Close-only, so wicks never move it. The classic Williams %R uses the window’s highest high and lowest low.