0bps

Strategy vault / Breakout

PB SAR Backtest Strategy with Elastic Stop Loss

This strategy is based on the elastic stop loss indicator, sets buy and sell signals, and performs long and short positions. When the indicator shows a buy signal, go long; when the indicator shows a sell signal, go…

Author
ChaoZhang
Complexity
Intermediate · 242 lines
Parameters
6
Backtest bar
2h · intraday
Tested on
BTC/USDT · futures

Overview

This strategy is based on the elastic stop loss indicator, sets buy and sell signals, and performs long and short positions. When the indicator shows a buy signal, go long; when the indicator shows a sell signal, go short. The strategy also combines a trailing stop loss mechanism to effectively control risks.

Principle

This strategy mainly uses the elastic stop loss indicator to identify the turning point of the trend and perform reversal operations. The true range indicator is used internally to identify extreme prices. When the price exceeds the extreme value, it is regarded as an abnormal breakthrough and the possibility of trend reversal is judged. Specifically, the indicator maintains two variables internally: extreme price (EP) and trigger price (TP). EP represents the highest or lowest price in the current trend. TP is calculated from EP.

In an upward trend, when the price is higher than EP, it is determined to be an abnormal breakthrough. At this time, EP is updated to the highest price and TP is the lowest price. When the price is lower than TP, the trend is determined to be reversed and a sell signal is generated. In a downtrend, the principle is similar.

This strategy combines a trailing stop loss mechanism. When a position is opened, the best stop loss price will be tracked in real time to ensure profits while controlling risks. Specifically, after going long, the stop loss line will track the closing low; after going short, the stop loss line will track the closing high.

Advantage

This strategy has the following advantages:

  1. Use indicators to identify trend reversal points and avoid being trapped.

  2. Trailing stop loss mechanism can lock in profits and avoid losses from expanding.

  3. Indicator parameters are simple and easy to implement.

  4. Configurable buying and selling signal prompts, easy to operate.

  5. Backtesting periods can be flexibly configured to comprehensively evaluate strategy performance.

Risk

This strategy also carries some risks:

  1. The indicator lags and may miss the best point for trend reversal.

  2. Stop-loss is too aggressive, may be triggered by short-term price fluctuations.

  3. Improper backtesting period selection cannot fully evaluate strategy effectiveness.

  4. Need to pay attention to the impact of transaction costs on profits.

Corresponding risk can be optimized from the following aspects:

  1. Adjust indicator parameters to reduce lag.

  2. Optimize stop-loss algorithm to avoid being trapped.

  3. Choose an appropriate backtesting period to ensure reliability.

  4. Optimize position management to reduce trading costs.

Optimization Direction

This strategy can be further optimized in the following aspects:

  1. Combine with trend indicators to avoid being trapped in reversal trades. You can add indicators such as MA to determine the general trend.

  2. Optimize position management algorithms, such as fixed proportion positions, dynamic positions, etc.

  3. Add trading volume filter to avoid false trades caused by gaps.

  4. Perform parameter optimization to find the best parameter combination.

  5. Add a take-profit strategy to secure profits in a trending market.

  6. Optimize stop-loss strategies to make stops smoother. Stop-loss algorithms like Chandelier Exit can be tested.

  7. Optimize trading instruments, time periods, etc., to improve strategy adaptability.

  8. Add machine learning algorithms to make the strategy more adaptive.

Summary

This strategy is relatively simple and reliable overall. It uses the elastic stop-loss indicator to identify reversal points and is equipped with a trailing stop-loss mechanism to control risks. It can be used as a short-term reversal strategy. However, we still need to pay attention to problems such as lagging indicators and too aggressive stop losses. Through further optimization, it is expected to obtain better strategic effects.

Overview

This strategy is based on the Parabolic SAR indicator to generate buy and sell signals for long and short positions. It also incorporates a trailing stop loss mechanism to effectively control risks.

Principle

The core of this strategy is to identify trend reversal points using the Parabolic SAR indicator for counter-trend trading. The indicator uses the true range to detect extreme prices. When the price exceeds the extreme, it is considered a breakout and a sign of potential trend reversal. Specifically, the indicator maintains two variables: the Extreme Price (EP) and the Trigger Price (TP). The EP represents the highest/lowest price of the current trend, while the TP is derived from the EP.

In an uptrend, when the price is higher than the EP, it is considered a breakout. The EP is then updated to the highest price and the TP to the lowest price. When the price falls below the TP, a trend reversal is identified and a sell signal is generated. The same principle applies for a downtrend.

The strategy also incorporates a trailing stop loss mechanism. After opening a position, it will track the optimal stop loss price in real-time, locking in profits while controlling risks. Specifically, after long entry, the stop loss tracks the closing low; after short entry, it tracks the closing high.

Advantages

The main advantages of this strategy are:

  1. Identify trend reversal points with the indicator, avoiding being trapped in trends.

  2. Trailing stop loss locks in profits and prevents wider losses.

  3. Simple indicator parameters, easy to implement.

  4. Configurable buy/sell signal alerts for convenience.

  5. Flexible backtest period configuration for thorough evaluation.

Risks

There are also some risks to consider:

  1. Indicator lag may miss optimal reversal points.

  2. Aggressive stops may be stopped out by short-term fluctuations.

  3. Improper backtest period selection cannot fully evaluate the strategy.

  4. Transaction costs may impair profits.

Some ways to address the risks are:

  1. Optimize parameters to reduce lag.

  2. Improve stop loss algorithm to avoid being stopped out unnecessarily.

  3. Select appropriate backtest periods for reliability.

  4. Optimize position sizing to lower transaction costs.

Enhancement

Some ways to further optimize the strategy:

  1. Incorporate trend indicators like MA to avoid being trapped in countertrends.

  2. Optimize position sizing algorithms, e.g. fixed fractional, dynamic.

  3. Add volume filter to avoid false signals from gaps.

  4. Parameter optimization to find optimal combinations.

  5. Implement profit taking strategies to lock in profits in trends.

  6. Refine stop loss algorithms for smoother stops. Experiment with Chandelier Exit etc.

  7. Optimize across products, time frames etc. to improve adaptability.

  8. Incorporate machine learning for greater adaptability.

Summary

In summary, this is a simple and robust strategy using the Parabolic SAR to identify reversals and trailing stop loss to control risk. It can work as a short-term mean-reversion strategy. But indicator lag and oversensitive stops need to be addressed. Further optimizations can lead to improved performance.

Parameters

NameDefaultWhat it controls
v_input_1trueStart Month
v_input_2trueStart Date
v_input_3(2019)Start Year
v_input_4trueEnd Month
v_input_5trueEnd Date
v_input_6(2020)End Year

Source Pine Script

/*backtest
start: 2023-09-10 00:00:00
end: 2023-10-10 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("PB SAR BackTest - Colorbar", overlay=false)

// Full credit to Sawcruhteez, Lucid Investment Strategies LLC, Casey Bowman and Peter Brandt.
// This is a strategy version of the Peterbolic SAR indicator created by the above-mentioned parties.
// Original version of the indicator: https://www.tradingview.com/script/6nYrH3Vm-Peterbolic-SAR/

// SAR #1
// Lucid Sar
// Branded under the name "Lucid SAR"
// as agreed to with Lucid Investment Strategies LLC on July 9, 2019
// https://lucidinvestmentstrategies.com/
// see branch "lucid"

// SAR #2
// Peterbolic Sar
// Using the name "Peterbolic SAR"
// as agreed to by Peter Brandt on October 2, 2019
// - https://twitter.com/PeterLBrandt/status/1179365590668075008
// in response to request from Sawcruhteez
// - https://twitter.com/Sawcruhteez/status/1179213105705836544
// Sawcruhteez gives credit to @CrazyGabey for coming up with the name
// - https://twitter.com/Sawcruhteez/status/1179213196583940097
// see branch "peterbolic"

// SAR #3
// Sawcruhteez Sar
// Branded under the name "Sawcruhteez SAR"
// as agreed to with Sawcruhteez on September 11, 2019
// see branch "sawcruhteez"

// Open Source on github
// https://github.com/casey-bowman/sar/blob/peterbolic/peterbolic.pine

// Created by Casey Bowman on July 4, 2019

// MIT License

// Copyright (c) 2019 Casey Bowman

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.



TSR() =>

    // start with uptrend
    var uptrend = true
    var EP = high       // extreme price - high or low depending on trend
    var SP = low        // setup price
    var TP = float(na)  // trigger price


    var setup   = low
    var trigger = float(na)

    if barstate.isnew
        setup := low
        trigger = float(na)

    extreme_candle = false
    first_extreme_candle = false
    setup_candle = false
    trigger_candle = false

    waiting_for_setup = false
    waiting_for_trigger = false

    var since_extreme = 0
    var since_setup = 0

    waiting_for_setup   := not extreme_candle and not na(SP)
    waiting_for_trigger := not na(TP)

    if not barstate.isfirst
        if barstate.isnew and extreme_candle[1]
            trigger := float(na)
        if barstate.isnew and setup_candle[1]
            setup := float(na)
        if barstate.isnew and waiting_for_trigger
            since_setup := since_setup + 1
            trigger := TP
        if barstate.isnew and waiting_for_setup
            since_extreme := since_extreme + 1
            setup := SP
        if uptrend

            if extreme_candle
                EP := high
                SP := low
            else
                if high > EP
                    extreme_candle := true
                    EP := high
                    SP := low
                    since_extreme := 0
                    since_setup   := 0
                else
                    if waiting_for_setup
                        if barstate.isconfirmed
                            if close < SP
                                setup_candle := true
                                SP := float(na)
                                TP := low
            if waiting_for_trigger
                if low < TP
                    trigger_candle := true
                    extreme_candle := true
                    EP := low
                    SP := high
                    TP := float(na)
                    uptrend := false
                    since_extreme := 0
                    since_setup := 0
                else
                    if barstate.isconfirmed and extreme_candle
                        TP := float(na)
                        trigger := float(na)

        else
            if extreme_candle
                EP := low
                SP := high
            else
                if low <  EP
                    extreme_candle := true
                    EP := low
                    SP := high
                    since_extreme := 0
                    since_setup   := 0
                else
                    if waiting_for_setup
                        if barstate.isconfirmed
                            if close > SP
                                setup_candle := true
                                SP := float(na)
                                TP := high
            if waiting_for_trigger
                if high > TP
                    trigger_candle := true
                    extreme_candle := true
                    EP := high
                    SP := low
                    TP := float(na)
                    uptrend := true
                    since_extreme := 0
                    since_setup := 0
                else
                    if barstate.isconfirmed and extreme_candle
                        TP := float(na)
                        trigger := float(na)


    [trigger_candle, trigger, since_setup, setup_candle, setup, since_extreme, extreme_candle, uptrend]


[TC, T, SS, SC, S, SE, EC, up] = TSR()

// Make input options that configure backtest date range
StartMonth = input(title="Start Month", type=input.integer,
     defval=1, minval=1, maxval=12)
StartDate = input(title="Start Date", type=input.integer,
     defval=1, minval=1, maxval=31)
StartYear = input(title="Start Year", type=input.integer,
     defval=(2019), minval=1800, maxval=2100)

EndMonth = input(title="End Month", type=input.integer,
     defval=1, minval=1, maxval=12)
EndDate = input(title="End Date", type=input.integer,
     defval=1, minval=1, maxval=31)
EndYear = input(title="End Year", type=input.integer,
     defval=(2020), minval=1800, maxval=2100)
     
// Look if the close time of the current bar falls inside the date range
inDateRange = true

buytrigger = (TC and up)
selltrigger = (TC and not up)
buysetup = (SC and not up)
sellsetup = (SC and up)

IntBuy = buytrigger ? 1 : 0
IntSB = buysetup ? 0.5 : 0

IntSell= selltrigger ? -1 : 0
IntSS = sellsetup ? -0.5 : 0

bgcolor = buytrigger ? color.green : selltrigger ? color.red : buysetup ? color.yellow : sellsetup ? color.orange : color.black
trans = buytrigger ? 20 : selltrigger ? 20 : 100

bgcolor(bgcolor, 30)

NUM = IntBuy + IntSB + IntSell + IntSS
linecolor = color.orange
plot(NUM, color=linecolor, linewidth=2)

alertcondition(NUM > 0.5, title="Buy Signal", message="Buy Alert")
alertcondition(NUM < -0.5, title="Sell Signal", message="Sell Alert")

alertcondition(NUM == 0.5, title="Buy Setup", message="Buy Setup")
alertcondition(NUM == -0.5, title="Sell Setup", message="Sell Setup")

//Switch on for strategy moves

if(inDateRange and buytrigger)
    strategy.exit("SHORT", "SHORT_SL", comment="Short_Exit")
    strategy.entry("LONG", strategy.long, comment="")
if(inDateRange and selltrigger)
    strategy.exit("LONG", "LONG_SL", comment="Long_Exit")
    strategy.entry("SHORT", strategy.short, comment="")
if (not inDateRange)
    strategy.close_all()

// plotshape(SC and not up, color = color.yellow, style = shape.triangleup, location = location.belowbar, size = size.auto, transp = 0, title = "Setup to Buy")
// plotshape(TC and up, color = color.green, style = shape.triangleup, location = location.belowbar, size = size.auto, title = "Trigger to Buy")
// plotshape(SC and up, color = color.yellow, style = shape.triangledown, location = location.abovebar, size = size.auto, transp = 0, title = "Setup to Sell")
// plotshape(TC and not up, color = color.red, style = shape.triangledown, location = location.abovebar, size = size.auto, title = "Trigger to Sell")

Published by ChaoZhang on the FMZ strategy square · last modified 2023-10-11. Collected in the Quant Trading Vault. Unvalidated research: re-test with your own data and costs before trusting it.

Build this with AgenKit

A spec is not a trading system. Paste this into your coding agent and AgenKit runs a specialist team — architecture, test-first build, risk gates, review — with paper trading on by default.

in Claude Code, Cursor, Codex & 4 more
/agenkit build a production-grade trading bot with a backtest engine, risk controls and paper trading by default from strategies/PB-SAR-Backtest-Strategy-with-Elastic-Stop-Loss.md
  1. npx agenkit install engineering-kit in your project
  2. Paste the command into your agent and approve each phase
  3. Get tests, backtest, risk controls and a paper-trading switch

Understand it first

Before you run this, read the lesson behind the idea and how to backtest it honestly. Specs like this one are the survivors of an unknown number of trials; deflate their results accordingly.

Related specs

esc

Try , , or .

↑↓ move↵ open