Skip to content
Open RaamTrade

WMA — Weighted Moving Average

Linearly-weighted moving average — the most recent close carries the highest weight. Single value. Draws on the price pane.

Signature

WMA(period, on=<source>)
Argument Type Required Notes
period int Param or literal Yes Lookback. Default 20, bounds 2–200.
on= symbol, OHLCV field, or indicator No Source. Defaults to the trade symbol’s close.

Formula

$$ \text{WMA} = \frac{\sum_{i=1}^{N} i \cdot \text{close}{(i)}}{\sum{i=1}^{N} i} $$

where close₍ᵢ₎ runs oldest → newest, so the newest bar gets weight N and the oldest weight 1.

Warmup

period bars. Before the window fills, the value is the simple average of the bars observed so far.

Reading the value

wma = WMA(20, on=self.trade)
wma.value
wma > slow_sma # comparisons read .value implicitly
wma.crossed_above(slow_sma)

Example

class WmaCross(Strategy):
"""Fast WMA crossing a slow SMA."""
fast_period = Param(10, min=2, max=50)
slow_period = Param(30, min=10, max=100)
trade = Symbol()
sizing = FixedCapital()
def execute(self):
fast = WMA(self.fast_period, on=self.trade)
slow = SMA(self.slow_period, on=self.trade)
self.stop_loss(2.0)
if fast.crossed_above(slow) and self.trade.is_flat:
self.buy(self.trade, reason="WMA over SMA")
if fast.crossed_below(slow) and self.trade.is_long:
self.sell(self.trade, self.trade.position, reason="WMA under SMA")

Notes

  • Responsiveness sits between SMA (slowest) and EMA (no hard window) — WMA reacts linearly and completely forgets bars older than period.
  • Same crossover mechanics as any single-value indicator — crossed_above / crossed_below work directly.