Skip to content
Open RaamTrade

ParabolicSAR — Parabolic SAR

Wilder’s stop-and-reverse: a trailing stop that accelerates toward price each time the move makes a new extreme, and flips to the other side when price touches it. Designed for markets that trend; in chop it whipsaws by construction.

Signature

ParabolicSAR(lookback, step, max_af, on=<source>)
Argument Type Required Notes
lookback int Param Yes Pinned at 2 (the two-bar clamp buffer). Bounds 2–2.
step float Param or literal Yes Acceleration increment. Default 0.02, bounds 0.001–0.5.
max_af float Param or literal Yes Acceleration cap. Default 0.2, bounds 0.01–1.0.
on= symbol No Source symbol. Defaults to the trade symbol. Reads high and low.

Formula

$$ \text{SAR}_{t+1} = \text{SAR}_t + AF,(EP - \text{SAR}_t) $$

EP is the current leg’s extreme; AF starts at step, grows by step on each new extreme, capped at max_af. In an uptrend the SAR may not rise above the prior two bars’ lows (mirror rule in a downtrend). On contact: flip direction, SAR jumps to EP, AF resets.

Warmup

Effectively none — the state machine starts on bar one (long, SAR at the first low) and becomes meaningful after the first flip.

Reading the value

sar.value
self.trade.close > sar.value # price above the stop = uptrend leg
sar.crossed_above(price) # a flip

Example

class SarFollower(Strategy):
"""Long while price holds above the SAR; exit when it touches."""
step = Param(0.02, min=0.001, max=0.5)
cap = Param(0.2, min=0.01, max=1.0)
trade = Symbol()
sizing = FixedCapital()
def execute(self):
sar = ParabolicSAR(2, self.step, self.cap, on=self.trade)
if self.trade.close > sar.value and self.trade.is_flat:
self.buy(self.trade, reason=f"Above SAR {sar.value:.2f}")
if self.trade.close < sar.value and self.trade.is_long:
self.sell(self.trade, self.trade.position, reason="SAR hit")

Notes

  • Wilder, New Concepts in Technical Trading Systems (1978), including the two-bar clamp most implementations forget.
  • Proven by an assert-via-trade run on SPY daily (agreed with an independent strategy-side replication, checked with a 5-bar persistence rule to tolerate flip-timing transients; zero alarm trades).
  • The lookback parameter exists only to size the clamp buffer; leave it at 2.
  • The recursion seeds from the first bar rather than from a warm-up window, so early values are not comparable with TA-Lib SAR(0.02, 0.2), which seeds from an average of the first n; measured on a 300-bar tape the two agree to 1e-6 from bar 162 onward.