Get the full strategy library: This article uses one strategy from the Mega Backtrader Strategy Pack, a package of 500+ Backtrader-ready Python trading strategies with batch backtesting, dashboards, metrics, charts, and documentation.
Download the package here: Mega Backtrader Strategy Pack
If you want to test complete Backtrader strategies without building every idea from scratch, the package gives you strategy code, batch runners, metrics, charts, and publishable reports in one workflow.
Parabolic SAR is a classic trend-following indicator. It is designed to trail price and flip when momentum changes direction. Used by itself, it can be noisy. Used with a trend filter, it becomes more selective.
This article walks through PsarTrendFilterStrategy, one
of the strategies included in the Mega Backtrader Strategy Pack. The
strategy was tested on BTC-USD daily candles from July 23, 2024
to July 23, 2026.
The result:
| Result | Value |
|---|---|
| Strategy return | 24.53% |
| BTC buy-and-hold return | -1.44% |
| Excess return | 25.97% |
| Sharpe ratio | 0.83 |
| Max drawdown | 9.30% |
| Closed trades | 13 |
| Open trades | 0 |
| Win rate | 69.23% |
This is a useful clean example because the run ended with 13 closed trades and no open position left behind. The return was not created by an unfinished trade.
PsarTrendFilterStrategy combines a moving-average regime
filter with Parabolic SAR flips.
The strategy uses three rules:
The important design choice is that the strategy does not take every Parabolic SAR flip. It only takes signals that agree with the broader moving-average trend.
The strategy exposes a small parameter set:
params = (
('ma_period', 30),
('psar_af', 0.01),
('psar_afmax', 0.1),
('trail_percent', 0.03),
)These settings control:
The strategy starts with a moving average for trend direction:
self.sma = bt.indicators.SimpleMovingAverage(
self.datas[0],
period=self.p.ma_period,
)It then creates the Parabolic SAR indicator:
self.psar = bt.indicators.ParabolicSAR(
self.datas[0],
af=self.p.psar_af,
afmax=self.p.psar_afmax,
)The entry signal is detected with a crossover between price and the Parabolic SAR value:
self.psar_cross = bt.indicators.CrossOver(
self.data.close,
self.psar,
)For long trades, price must first be above the moving average:
if self.data.close[0] > self.sma[0]:
if self.psar_cross[0] > 0.0:
self.order = self.buy()That means the strategy only buys when the market is already above the trend filter and price crosses above PSAR.
For short trades, price must first be below the moving average:
elif self.data.close[0] < self.sma[0]:
if self.psar_cross[0] < 0.0:
self.order = self.sell()That keeps short entries aligned with a weaker trend regime.
After a completed long entry, the strategy places a trailing sell stop:
if order.isbuy():
self.sell(
exectype=bt.Order.StopTrail,
trailpercent=self.p.trail_percent,
)After a completed short entry, it places a trailing buy stop:
elif order.issell():
self.buy(
exectype=bt.Order.StopTrail,
trailpercent=self.p.trail_percent,
)That gives the strategy a complete structure: filter the market regime, enter on a PSAR flip, and let the trailing stop manage the exit.
The article result was generated with:
python run_backtest.py --fast --fast-plots --fast-equity \
--workers 1 \
--symbol BTC-USD \
--period 2y \
--interval 1d \
--benchmark BTC-USD \
--stake-percent 99 \
--strategies strategies \
--out results \
--strategy-filter PsarTrendFilterStrategy.pyBacktest setup:
| Setting | Value |
|---|---|
| Asset | BTC-USD |
| Benchmark | BTC-USD buy-and-hold |
| Period | 2y |
| Data window | July 23, 2024 to July 23, 2026 |
| Interval | 1d |
| Starting cash | $10,000 |
| Final value | $12,452.55 |
| Strategy file | strategies/PsarTrendFilterStrategy.py |
| Metric | Value |
|---|---|
| Strategy return | 24.53% |
| BTC buy-and-hold return | -1.44% |
| Excess return vs benchmark | 25.97% |
| Sharpe ratio | 0.83 |
| Max drawdown | 9.30% |
| Total trades | 13 |
| Closed trades | 13 |
| Open trades | 0 |
| Winning trades | 9 |
| Losing trades | 4 |
| Win rate | 69.23% |
| Runtime | 2.31 seconds |
This strategy did not produce the largest return in the library, but it is a strong example of a compact, readable trading system that produced positive results with controlled drawdown and no unresolved open trade.
The equity curve shows the strategy growing from $10,000 to $12,452.55 while BTC buy-and-hold finished slightly negative over the same two-year window.
The drawdown chart shows a maximum strategy drawdown of 9.30%.
The rolling return chart shows how the strategy's performance developed through the backtest window.
The daily return distribution gives a compact view of the strategy's day-to-day behavior.
This strategy is a good example of why small systems still matter inside a large research library.
The logic is easy to understand:
Simple strategies are useful because they are easy to inspect, modify, combine, and benchmark. In a large package, they also serve as building blocks for more advanced research.
PsarTrendFilterStrategy is one of 500+
Backtrader-ready strategies included in the Mega
Backtrader Strategy Pack.
Get the full package here: Mega Backtrader Strategy Pack
The package includes:
strategies/
package.If you want to test more strategy ideas faster, this package gives you the code and the research workflow.
Get the Mega Backtrader Strategy Pack
This article is for research and educational use only. Backtest results are not financial advice, investment advice, or a guarantee of future performance. Always validate strategy logic, data quality, execution assumptions, costs, slippage, and risk before using any trading system.