QuantLearn
Trading Strategies
Parabolic SAR
Stop and reverse trend following system
Parabolic SAR Backtest Results
Historical backtesting on Electronic Arts (EA) stock demonstrating the Parabolic SAR trend following system.

Parabolic SAR Trading Signals
Price chart with Parabolic SAR dots and trading signals. Green arrows indicate long entries when price crosses above SAR, red arrows show short entries when price falls below SAR.
Parabolic Stop and Reverse Theory
Parabolic SAR (Stop and Reverse) is a trend-following indicator developed by J. Welles Wilder, the same creator of RSI.
The indicator appears as a series of dots positioned above or below the price chart, acting as dynamic support and resistance levels.
When SAR dots are below the price, it indicates an uptrend; when above, it signals a downtrend.
The SAR "flips" when price crosses through the dots, providing clear trend reversal signals.
The indicator accelerates as the trend progresses, tightening the stop-loss level to protect profits.
Parabolic SAR works best in trending markets but can generate false signals in sideways conditions.
The calculation involves complex recursive mathematics that account for extreme points and acceleration factors.
Parabolic SAR Calculation
1Basic SAR Formula
Current SAR plus acceleration factor times the difference between extreme point and current SAR.
2Acceleration Factor Progression
AF starts at 0.02, increases by 0.02 for each new extreme point, capped at 0.20 for most assets.
3Rising SAR Constraint
In uptrends, SAR cannot exceed the lowest low of the previous two periods.
4Falling SAR Constraint
In downtrends, SAR cannot fall below the highest high of the previous two periods.
5Trend Reversal Condition
When price crosses the SAR level, the trend direction reverses and SAR switches sides.
Parabolic SAR Implementation
The algorithm involves recursive calculations with trend tracking, extreme point monitoring, and acceleration factor management.
SAR Calculation Engine
def parabolic_sar(data):
# Standard SAR parameters for forex/commodities
initial_af = 0.02
step_af = 0.02
end_af = 0.2
data['trend'] = 0
data['sar'] = 0.0
data['real sar'] = 0.0
data['ep'] = 0.0 # Extreme Point
data['af'] = 0.0 # Acceleration Factor
# Initialize first values
data['trend'][1] = 1 if data['Close'][1] > data['Close'][0] else -1
data['sar'][1] = data['High'][0] if data['trend'][1] > 0 else data['Low'][0]
data.at[1, 'real sar'] = data['sar'][1]
data['ep'][1] = data['High'][1] if data['trend'][1] > 0 else data['Low'][1]
data['af'][1] = initial_af
# Recursive calculation for each period
for i in range(2, len(data)):
# Calculate tentative SAR
temp = data['sar'][i-1] + data['af'][i-1] * (data['ep'][i-1] - data['sar'][i-1])
# Apply constraints based on trend direction
if data['trend'][i-1] < 0: # Downtrend
data.at[i, 'sar'] = max(temp, data['High'][i-1], data['High'][i-2])
temp = 1 if data['sar'][i] < data['High'][i] else data['trend'][i-1] - 1
else: # Uptrend
data.at[i, 'sar'] = min(temp, data['Low'][i-1], data['Low'][i-2])
temp = -1 if data['sar'][i] > data['Low'][i] else data['trend'][i-1] + 1
data.at[i, 'trend'] = temp
# Update Extreme Point
if data['trend'][i] < 0:
temp = min(data['Low'][i], data['ep'][i-1]) if data['trend'][i] != -1 else data['Low'][i]
else:
temp = max(data['High'][i], data['ep'][i-1]) if data['trend'][i] != 1 else data['High'][i]
data.at[i, 'ep'] = temp
# Update Acceleration Factor
if abs(data['trend'][i]) == 1: # Trend reversal
temp = data['ep'][i-1]
data.at[i, 'af'] = initial_af
else:
temp = data['sar'][i]
if data['ep'][i] == data['ep'][i-1]: # No new extreme
data.at[i, 'af'] = data['af'][i-1]
else: # New extreme point
data.at[i, 'af'] = min(end_af, data['af'][i-1] + step_af)
data.at[i, 'real sar'] = temp
return dataComplex recursive calculation that tracks trend direction, extreme points, and dynamically adjusts the SAR level with acceleration factors.
Signal Generation
def signal_generation(df, method):
data = method(df)
data['positions'] = 0
data['signals'] = 0
# Generate position signals based on SAR vs price relationship
data['positions'] = np.where(data['real sar'] < data['Close'], 1, 0)
# Convert positions to entry/exit signals
data['signals'] = data['positions'].diff()
return dataGenerates trading signals when price crosses above (buy) or below (sell) the Parabolic SAR level.
Trend Visualization
def plot(data, ticker):
fig = plt.figure()
ax = fig.add_subplot(111)
# Plot price and SAR
data['Close'].plot(lw=3, label=f'{ticker}')
data['real sar'].plot(linestyle=':', label='Parabolic SAR', color='k')
# Mark trading signals
ax.plot(data.loc[data['signals'] == 1].index,
data['Close'][data['signals'] == 1],
marker='^', color='g', label='LONG', lw=0, markersize=10)
ax.plot(data.loc[data['signals'] == -1].index,
data['Close'][data['signals'] == -1],
marker='v', color='r', label='SHORT', lw=0, markersize=10)
plt.legend()
plt.grid(True)
plt.title('Parabolic SAR Strategy')
plt.ylabel('Price')
plt.show()Visualizes the price chart with SAR dots and clearly marks entry/exit points for trend following trades.
Implementation Steps
- 1Download historical OHLC data with sufficient history for SAR calculation
- 2Initialize SAR parameters: AF start (0.02), AF step (0.02), AF max (0.20)
- 3Calculate initial trend direction based on first two closing prices
- 4Implement recursive SAR calculation with trend tracking and extreme point monitoring
- 5Apply SAR constraints to prevent unrealistic values during trend reversals
- 6Generate trading signals when price crosses the SAR level
- 7Implement position management with proper entry and exit timing
- 8Monitor performance and adjust AF parameters for different asset classes
Key Metrics
Risk Considerations
Practice Implementation
Prerequisites
Mathematical Background
- • Linear regression and OLS estimation
- • Time series analysis (stationarity, unit roots)
- • Hypothesis testing and p-values
- • Basic econometrics (error correction models)
Technical Skills
- • Python programming (pandas, numpy)
- • Statistical libraries (statsmodels)
- • Data visualization (matplotlib)
- • Financial data handling (yfinance)
Complete Implementation
Access the full Python implementation from the original quantitative trading repository:
# Complete pair trading implementation
git clone https://github.com/je-suis-tm/quant-trading.git
cd quant-trading
python "Pair trading backtest.py"
# Modify tickers and parameters for your own analysisLearning Checkpoints
Understand Cointegration
Can you explain why two assets might be cointegrated and what breaks this relationship?
Interpret Statistical Tests
Practice reading ADF test results and understanding when to accept/reject cointegration.
Signal Generation
Implement Z-score calculations and understand threshold selection (±1σ vs ±2σ).
Risk Management
Understand position sizing, monitoring regime changes, and exit strategies.
Recommended Learning Path
Immediate Actions
- Download and run the Python script
- Test with different asset pairs
- Experiment with threshold parameters
Advanced Studies
- Learn Johansen cointegration test
- Study Vector Error Correction Models
- Explore multiple asset pair trading
Important Disclaimer
This strategy involves significant risk. Historical cointegration relationships can break permanently. Always use proper risk management, position sizing, and never risk more than you can afford to lose. Paper trade extensively before using real capital.