In the previous chapter, we observed the Parabolic SAR indicator in action with Reliance Industries. Now, we will dissect the algorithm’s mechanics to build a robust, quantitative understanding. This lesson transitions from visual observation to the underlying logic, preparing you to implement and test the strategy programmatically.
We will cover:
This deep dive will equip you with the foundational knowledge required to move beyond simple chart plotting and into systematic backtesting and deployment.
The Parabolic SAR was developed by J. Welles Wilder Jr., the creator of other seminal indicators like the Relative Strength Index (RSI) and the Average Directional Index (ADX). Its primary purpose is to identify potential trend reversals, hence the name “Stop and Reverse” (SAR).
The indicator plots dots on the chart that trail the price, acting as a dynamic trailing stop loss. The calculation is iterative, meaning each period’s SAR value depends on the previous period’s value.
The core formula is as follows:
For an uptrend:
For a downtrend:
Let’s break down the components:
The behaviour of the Parabolic SAR is governed by three key parameters:
The strategy’s logic is fundamentally built on trend identification and reversal detection.
Upon reversal, the SAR value for the new trend is reset to the Extreme Point of the prior trend. The AF is also reset to its initial ‘start’ value.
Let’s walk through a calculation with a synthetic 5-day series for NIFTY Futures. We will use the standard parameters: Start = 0.02, Increment = 0.02, Maximum = 0.20.
Here is our price data:
| Day | High | Low | Trend | EP | AF | SAR | Remark |
|---|---|---|---|---|---|---|---|
| 1 | 18,550 | 18,480 | Up | 18,550 | 0.02 | 18,480 | Initial state after Day 1 establishes an uptrend. SAR is set to the Low, EP to the High. |
| 2 | 18,610 | 18,560 | Up | 18,610 | 0.04 | 18,481.40 | New High made. AF increased. |
| 3 | 18,650 | 18,590 | Up | 18,650 | 0.06 | 18,486.57 | New High made. AF increased. |
| 4 | 18,630 | 18,500 | Down | 18,500 | 0.02 | 18,500.54 | REVERSAL. Low breaches SAR. New SAR is prior EP. |
| 5 | 18,520 | 18,450 | Down | 18,450 | 0.04 | 18,650.00 | New Low made. AF increased. SAR continues down. |
End of Day 1:
We need two periods to begin, but after Day 1, we establish our initial state. We assume the trend is UP.
Day 2:
Day 3:
Day 4: REVERSAL
Day 5:
To automate this strategy, we need to translate the rules into a structured algorithm.
Initialize parameters: start_af, increment_af, max_af.
Initialize state variables: is_uptrend, extreme_point (EP), current_sar, current_af.
For each price bar (candle), starting from the second bar:
// Determine initial trend from the first two bars
If this is the first calculation:
If close > previous_close:
is_uptrend = True
EP = high
current_sar = low
Else:
is_uptrend = False
EP = low
current_sar = high
current_af = start_af
Continue to next bar.
// Store the SAR value for the current bar before calculating the next one
plot_sar = current_sar
// Check for reversal
If is_uptrend:
If current_bar.low <= current_sar:
// Trend flips from UP to DOWN
is_uptrend = False
current_sar = EP // The new SAR is the old Extreme Point
EP = current_bar.low
current_af = start_af
Continue to next bar.
Else (is_downtrend):
If current_bar.high >= current_sar:
// Trend flips from DOWN to UP
is_uptrend = True
current_sar = EP // The new SAR is the old Extreme Point
EP = current_bar.high
current_af = start_af
Continue to next bar.
// If no reversal, update EP and AF for the ongoing trend
If is_uptrend:
If current_bar.high > EP:
EP = current_bar.high
current_af = min(current_af + increment_af, max_af)
Else (is_downtrend):
If current_bar.low < EP:
EP = current_bar.low
current_af = min(current_af + increment_af, max_af)
// Calculate the SAR for the *next* bar
next_sar = current_sar + current_af * (EP - current_sar)
// Apply failsafe rules (SAR should not move into the prior two periods' price range)
If is_uptrend:
next_sar = min(next_sar, previous_bar.low, two_bars_ago.low)
Else (is_downtrend):
next_sar = max(next_sar, previous_bar.high, two_bars_ago.high)
// Update current SAR for the next iteration
current_sar = next_sar
Here is a Python class that encapsulates the logic described above. This code processes a list of price bars (represented as dictionaries) and calculates the SAR values.
class ParabolicSARStrategy:
def __init__(self, start=0.02, increment=0.02, maximum=0.2):
self.start = start
self.increment = increment
self.maximum = maximum
self.uptrend = None
self.EP = None
self.SAR = None
self.AF = start
self.nextBarSAR = None
self.firstTrendBar = False
def calculate(self, bars):
# This method would typically return a list of SAR values
sar_values = [None] * len(bars)
for i in range(1, len(bars)): # Start from the second bar
self.firstTrendBar = False
# Initial trend determination
if i == 1:
prev_low, prev_high = bars[i-1]['low'], bars[i-1]['high']
curr_close, prev_close = bars[i]['close'], bars[i-1]['close']
if curr_close > prev_close:
self.uptrend = True
self.EP = bars[i]['high']
self.SAR = prev_low
else:
self.uptrend = False
self.EP = bars[i]['low']
self.SAR = prev_high
self.AF = self.start
self.firstTrendBar = True
# Use the SAR calculated from the previous bar for today's logic
sar_values[i] = self.SAR
# Check for reversal
if self.uptrend:
if self.SAR > bars[i]['low']: # Reversal from up to down
self.firstTrendBar = True
self.uptrend = False
self.SAR = max(self.EP, bars[i]['high']) # SAR is the prior EP
self.EP = bars[i]['low']
self.AF = self.start
else: # Downtrend
if self.SAR < bars[i]['high']: # Reversal from down to up
self.firstTrendBar = True
self.uptrend = True
self.SAR = min(self.EP, bars[i]['low']) # SAR is the prior EP
self.EP = bars[i]['high']
self.AF = self.start
# If no reversal, update EP and AF
if not self.firstTrendBar:
if self.uptrend:
if bars[i]['high'] > self.EP:
self.EP = bars[i]['high']
self.AF = min(self.AF + self.increment, self.maximum)
else: # Downtrend
if bars[i]['low'] < self.EP:
self.EP = bars[i]['low']
self.AF = min(self.AF + self.increment, self.maximum)
# Calculate SAR for the next bar
self.nextBarSAR = self.SAR + self.AF * (self.EP - self.SAR)
# Apply Wilder's failsafe rules to prevent SAR from moving inside previous price action
if self.uptrend:
if i > 1:
self.nextBarSAR = min(self.nextBarSAR, bars[i-1]['low'], bars[i-2]['low'])
else: # Downtrend
if i > 1:
self.nextBarSAR = max(self.nextBarSAR, bars[i-1]['high'], bars[i-2]['high'])
# Update SAR for the next iteration
self.SAR = self.nextBarSAR
return sar_values
# Usage:
# bars = [{'open': o, 'high': h, 'low': l, 'close': c}, ...]
# strategy = ParabolicSARStrategy()
# sar_results = strategy.calculate(bars)
While the Parabolic SAR provides a structured approach, it is not infallible. Its performance is highly dependent on market conditions.
A common practice is to combine the Parabolic SAR with a trend-strength indicator like the Average Directional Index (ADX). A simple rule could be to only take SAR signals when the ADX is above a certain threshold (e.g., 20 or 25), confirming that a tangible trend is in place.
By understanding the mathematical and algorithmic foundations of the Parabolic SAR, you are better equipped to assess its strengths, weaknesses, and appropriate use cases in your own trading systems.