Burgle Bounce is a price-chart strategy that treats a move toward one of up to four simple or exponential moving averages as a test when price comes within a user-set percentage of ATR, then exits toward a target average under a separate error margin.
1Copy the scriptPress Copy script above, or the copy button on the code below.
2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
3Paste over the templateCreate a new strategy, select all of the template text and paste. Press Save and give it a name.
4Add it to the chartPress Add to chart. The trades and results appear in the Strategy Tester tab; adjust the settings with the gear icon.
Source Code
293 lines of Pine Script v5 from Burgle Bounce.pine, published under MPL-2.0. Keep the author's credit and licence lines when you reuse it.
Burgle Bounce.pine
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//
// Author: benso87
// benso87.com
//
// Credit to:
// Burglekutt for the strategy
// Eric Crown for the strategy inspiration
// The_Caretaker for the indicators referenced for calculations.
//
//@version=5
strategy("Burgle Bounce", overlay=true, initial_capital=1000, default_qty_value=10, default_qty_type=strategy.percent_of_equity, calc_on_every_tick=true, process_orders_on_close=true, backtest_fill_limits_assumption=1)
noColor = color.new(color.white, transp=100)
///////////////////////////////////////////////////////////////////////////////
// Inputs
//Dates
startDate = input.time (timestamp('1 Jan 2022 00:00'), title='Start', group='Dates')
endDate = input.time (timestamp('1 Jan 2100 00:00'), title='End', group='Dates')
// General
errorMarginTestInput = input.float (10, title='Error Margin For Test (%)', minval=0, group='General', tooltip='Price needs to get within this percentage of the ATR (length specified below) to the MA to be considered a test.')
errorMarginExitInput = input.float (10, title='Error Margin For Exit (%)', minval=0, group='General', tooltip='Price neesd to get within this percentage of the ATR (length specified below) to the target MA to exit')
// minTargetInput = input.float(0.5, title='Min Profit %', minval=0, group='General', tooltip='Only take a trade if the target would make at least this much profit')
// Moving average inputs
includeMA1 = input.bool (true, title='', inline='MA 1', group='Moving Averages')
ma1Color = input.color (#ffeb3b, title='MA 1', inline='MA 1', group='Moving Averages')
ma1Length = input.int (21, title='Length', minval=1, inline='MA 1', group='Moving Averages')
ma1Type = input.string ('EMA', title='Type', options=['SMA','EMA'], inline='MA 1', group='Moving Averages')
includeMA2 = input.bool (true, title='', inline='MA 2', group='Moving Averages')
ma2Color = input.color (#00e676, title='MA 2', inline='MA 2', group='Moving Averages')
ma2Length = input.int (55, title='Length', minval=1, inline='MA 2', group='Moving Averages')
ma2Type = input.string ('EMA', title='Type', options=['SMA','EMA'], inline='MA 2', group='Moving Averages')
includeMA3 = input.bool (true, title='', inline='MA 3', group='Moving Averages')
ma3Color = input.color (#00bcd4, title='MA 3', inline='MA 3', group='Moving Averages')
ma3Length = input.int (100, title='Length', minval=1, inline='MA 3', group='Moving Averages')
ma3Type = input.string ('EMA', title='Type', options=['SMA','EMA'], inline='MA 3', group='Moving Averages')
includeMA4 = input.bool (true, title='', inline='MA 4', group='Moving Averages')
ma4Color = input.color (#e040fb, title='MA 4', inline='MA 4', group='Moving Averages')
ma4Length = input.int (200, title='Length', minval=1, inline='MA 4', group='Moving Averages')
ma4Type = input.string ('EMA', title='Type', options=['SMA','EMA'], inline='MA 4', group='Moving Averages')
//Signal inputs
includeLongs = input.bool ( true, 'Longs', inline='1', group='Signal Settings')
rsiLongLimit = input.float ( 38, 'RSI long limit', minval=0.1, maxval=100, step=0.01, inline='2', group='Signal Settings')
pmarp_long_signal = input.float ( 15, 'PMARP long signal', minval=0.1, maxval=100, step=0.01, inline='3', group='Signal Settings')
includeShorts = input.bool ( true, 'Shorts', inline='4', group='Signal Settings')
rsiShortLimit = input.float ( 62, 'RSI short limit', minval=0.1, maxval=100, step=0.01, inline='5', group='Signal Settings')
pmarp_short_signal = input.float ( 85, 'PMARP short signal', minval=0.1, maxval=100, step=0.01, inline='6', group='Signal Settings')
// RSI settings
rsiPeriod = input.int ( 14, minval=1, title="RSI Period", group="RSI Settings", inline="01")
rsiSource = input.source ( close, title="Source", group="RSI Settings", inline="01")
rsiSignalPeriod = input.int ( 12, minval=1, title="Signal Period", group="RSI Settings", inline="02")
rsiSignalType = input.string ( "EMA", title="Type", options=["SMA", "EMA"], group="RSI Settings", inline="02")
rsiExits = input.bool ( true, title='Use RSI for SL', group='RSI Settings', inline='03')
// RSI levels
rsiBullControl = input.int ( 62, title="Bull Control Level", group="Levels", inline="01")
rsiBearControl = input.int ( 38, title="Bear Control Level", group="Levels", inline="02")
// PMARP inputs
i_src_price = input.source ( close, 'Price source', group='PMARP Properties', inline='1')
i_pmarp_lookback = input.int ( 350, 'Lookback', minval=1, maxval=1900, group='PMARP Properties', inline='1')
i_ma_len = input.int ( 20, 'PMAR length', minval=1, group='PMARP Properties', inline='2')
i_ma_typ = input.string ( 'VWMA', 'MA type...', options=[ 'SMA', 'EMA', 'HMA', 'RMA', 'VWMA' ], group='PMARP Properties', inline='2')
//BBWP inputs
useBBWP = input.bool ( false, 'Use BBWP', inline='1', group='BBWP Properties')
bbwpThreshold = input.float (35, 'Above', minval=0, maxval=100, inline='2', group='BBWP Properties')
i_priceSrc = input.source ( close, 'Price Source', inline='3', group='BBWP Properties')
i_basisType = input.string ( 'SMA', 'Basis Type', options=['SMA', 'EMA', 'VWMA'], inline='3', group='BBWP Properties')
i_bbwpLen = input.int ( 13, 'Length', minval=1, inline='4', group='BBWP Properties')
i_bbwpLkbk = input.int ( 252, 'Lookback', minval=1, inline='4', group='BBWP Properties')
///////////////////////////////////////////////////////////////////////////////
// Credit to The_Caretaker
// PMARP
// PMARP function declarations
f_prior_sum ( _P, _X ) =>
math.sum ( _P[1], _X - 1 )
f_ma_val ( _P, _typ, _len ) =>
_typ == 'SMA' ? ta.sma ( _P, _len ) : _typ == 'EMA' ? ta.ema ( _P, _len ) : _typ == 'RMA' ? ta.rma ( _P, _len ) : _typ == 'HMA' ? ta.hma ( _P, _len ) : ta.vwma ( _P, _len )
f_pmarp ( _price, _pmarLen, _pmarpLen, _type_p ) =>
_pmar = math.abs ( _price / f_ma_val ( _price, _type_p, _pmarLen ))
_pmarpSum = 0
_len = bar_index < _pmarpLen ? bar_index : _pmarpLen
for i = 1 to _len by 1
_pmarpSum += ( _pmar[i] > _pmar ? 0 : 1 )
_pmarpSum
_return = bar_index >= _pmarLen ? _pmarpSum / _len * 100 : na
// PMARP calculations
ma = f_ma_val ( i_src_price, i_ma_typ, i_ma_len )
pmar = i_src_price / ma
pmarp = f_pmarp ( i_src_price, i_ma_len, i_pmarp_lookback, i_ma_typ )
///////////////////////////////////////////////////////////////////////////////
// bbwp
// function declarations
f_maType ( _price, _len, _type ) =>
_type == 'SMA' ? ta.sma ( _price, _len ) : _type == 'EMA' ? ta.ema ( _price, _len ) : ta.vwma ( _price, _len )
f_bbwp ( _price, _bbwLen, _bbwpLen, _type ) =>
float _basis = f_maType ( _price, _bbwLen, _type )
float _dev = ta.stdev ( _price, _bbwLen )
_bbw = ( _basis + _dev - ( _basis - _dev )) / _basis
_bbwSum = 0.0
_len = bar_index < _bbwpLen ? bar_index : _bbwpLen
for _i = 1 to _len by 1
_bbwSum += ( _bbw[_i] > _bbw ? 0 : 1 )
_bbwSum
_return = bar_index >= _bbwLen ? ( _bbwSum / _len) * 100 : na
_return
///////////////////////////////////////////////////////////////////////////////
// calculations
bbwp = f_bbwp ( i_priceSrc, i_bbwpLen, i_bbwpLkbk, i_basisType )
///////////////////////////////////////////////////////////////////////////////
// Calculations
// Minimum target
// minTarget = minTargetInput / 100
// Error margins
errorMarginTest = errorMarginTestInput / 100
errorMarginExit = errorMarginExitInput / 100
// // Swings
// pvthi_ = ta.pivothigh(high, pvtLenL, pvtLenR)
// pvtlo_ = ta.pivotlow(low, pvtLenL, pvtLenR)
// // Force Pivot completion before plotting.
// Shunt = 0 //Wait for close before printing pivot? 1 for true 0 for false
// maxLvlLen = 0 //Maximum Extension Length
// pvthi = pvthi_[Shunt]
// pvtlo = pvtlo_[Shunt]
// // Count How many candles for current Pivot Level, If new reset.
// counthi = ta.barssince(not na(pvthi))
// countlo = ta.barssince(not na(pvtlo))
// pvthis = fixnan(pvthi)
// pvtlos = fixnan(pvtlo)
// hipc = ta.change(pvthis) != 0 ? na : #ff0014
// lopc = ta.change(pvtlos) != 0 ? na : #0bff00
// Moving average calculations
ma1 = ta.ema(close, ma1Length)
ma2 = ta.ema(close, ma2Length)
ma3 = ta.ema(close, ma3Length)
ma4 = ta.ema(close, ma4Length)
ma1Above2 = ma1 > ma2
ma2Above3 = ma2 > ma3
ma3Above4 = ma3 > ma4
ma1Below2 = ma1 < ma2
ma2Below3 = ma2 < ma3
ma3Below4 = ma3 < ma4
maInOrder = (ma1Above2 and ma2Above3 and ma3Above4) or (ma1Below2 and ma2Below3 and ma3Below4)
ma12mid = math.avg(ma1, ma2)
ma23mid = math.avg(ma2, ma3)
ma34mid = math.avg(ma3, ma4)
silverCross = ta.crossover(ma1, ma2)
darkCross = ta.crossover(ma2, ma1)
ma2ishLong = ma2 + math.abs(ma1 - ma2) * errorMarginTest
ma2ishShort = ma2 - math.abs(ma1 - ma2) * errorMarginTest
ma3ishLong = ma3 + math.abs(ma2 - ma3) * errorMarginTest
ma3ishShort = ma3 - math.abs(ma2 - ma3) * errorMarginTest
ma4ishLong = ma4 + math.abs(ma3 - ma4) * errorMarginTest
ma4ishShort = ma4 - math.abs(ma3 - ma4) * errorMarginTest
ma1ishTPLong = ma1 - math.abs(ma1 - ma2) * errorMarginTest
ma1ishTPShort = ma1 + math.abs(ma1 - ma2) * errorMarginTest
ma2ishTPLong = ma2 - math.abs(ma2 - ma3) * errorMarginTest
ma2ishTPShort = ma2 + math.abs(ma2 - ma3) * errorMarginTest
ma3ishTPLong = ma3 - math.abs(ma3 - ma4) * errorMarginTest
ma3ishTPShort = ma3 + math.abs(ma3 - ma4) * errorMarginTest
ma2TestLong = ((low <= ma2ishLong and close >= ma2) or (close[1] < ma2ishLong[1] and close >= ma2) or (close <= ma2ishLong and close >= ma2ishShort)) and close <= ma12mid
ma3TestLong = ((low <= ma3ishLong and close >= ma3) or (close[1] < ma3ishLong[1] and close >= ma3) or (close <= ma3ishLong and close >= ma3ishShort)) and close <= ma23mid
ma4TestLong = ((low <= ma4ishLong and close >= ma4) or (close[1] < ma4ishLong[1] and close >= ma4) or (close <= ma4ishLong and close >= ma4ishShort)) and close <= ma34mid
ma2TestShort = ((high >= ma2ishShort and close <= ma2) or (close[1] > ma2ishShort[1] and close <= ma2) or (close <= ma2ishShort and close >= ma2ishLong)) and close >= ma12mid
ma3TestShort = ((high >= ma3ishShort and close <= ma3) or (close[1] > ma3ishShort[1] and close <= ma3) or (close <= ma3ishShort and close >= ma3ishLong)) and close >= ma23mid
ma4TestShort = ((high >= ma4ishShort and close <= ma4) or (close[1] > ma4ishShort[1] and close <= ma4) or (close <= ma4ishShort and close >= ma4ishLong)) and close >= ma34mid
maLongSignal = ma1Above2 and close < ma1 and (ma2TestLong or ma3TestLong or ma4TestLong) and maInOrder
maShortSignal = ma1Below2 and close > ma1 and (ma2TestShort or ma3TestShort or ma4TestShort) and maInOrder
// RSI calculations
rsiUp = ta.rma(math.max(ta.change(rsiSource), 0), rsiPeriod)
rsiDown = ta.rma(-math.min(ta.change(rsiSource), 0), rsiPeriod)
rsi = rsiDown == 0 ? 100 : rsiUp == 0 ? 0 : 100 - (100 / (1 + rsiUp / rsiDown))
rsiLongSignal = rsi > rsiLongLimit
rsiLongExitSignal = rsi <= rsiLongLimit
rsiShortSignal = rsi < rsiShortLimit
rsiShortExitSignal = rsi >= rsiShortLimit
// PMARP calculations
pmarpLongSignal = pmarp <= pmarp_long_signal
pmarpShortSignal = pmarp >= pmarp_short_signal
// BBWP calculations
bbwpSignal = bbwp >= bbwpThreshold or not useBBWP
// Signal calculations
longSignal = includeLongs and strategy.opentrades == 0 and barstate.isconfirmed and close <= open and maLongSignal and rsiLongSignal and pmarpLongSignal and bbwpSignal and time >= startDate and time <= endDate
shortSignal = includeShorts and strategy.opentrades == 0 and barstate.isconfirmed and close >= open and maShortSignal and rsiShortSignal and pmarpShortSignal and bbwpSignal and time >= startDate and time <= endDate
// Save which EMA was tested
var int emaTested = na
var int emaTarget = na
if longSignal
if ma2TestLong
emaTested := 2
else if ma3TestLong
emaTested := 3
else if ma4TestLong
emaTested := 4
if shortSignal
if ma2TestShort
emaTested := 2
else if ma3TestShort
emaTested := 3
else if ma4TestShort
emaTested := 4
// Stop losses
slLong = (rsiExits and rsiLongExitSignal) or silverCross
slShort = (rsiExits and rsiShortExitSignal) or darkCross
// Take profits
tpLong = emaTested == 2 ? ma1ishTPLong[1] : emaTested == 3 ? ma2ishTPLong[1] : emaTested == 4 ? ma3ishTPLong[1] : na
tpShort = emaTested == 2 ? ma1ishTPShort[1] : emaTested == 3 ? ma2ishTPShort[1] : emaTested == 4 ? ma3ishTPShort[1] : na
///////////////////////////////////////////////////////////////////////////////
// Plots
// Background
bgcolor(ma1Above2 and maInOrder ? color.new(color.green, transp=80) : ma1Below2 and maInOrder? color.new(color.red, transp=80) : na)
// Moving averages
plot(includeMA1 ? ma1 : na, title='MA 1', color=ma1Color, linewidth=2, offset=0)
plot(includeMA2 ? ma2 : na, title='MA 2', color=ma2Color, linewidth=2, offset=0)
plot(includeMA3 ? ma3 : na, title='MA 3', color=ma3Color, linewidth=2, offset=0)
plot(includeMA4 ? ma4 : na, title='MA 4', color=ma4Color, linewidth=2, offset=0)
///////////////////////////////////////////////////////////////////////////////
// Strategy conditions
strategy.entry("LONG", strategy.long, when=longSignal)
strategy.exit("LONG", limit=tpLong)
strategy.close("LONG", when=slLong)
strategy.entry("SHORT", strategy.short, when=shortSignal)
strategy.exit("SHORT", limit=tpShort)
strategy.close("SHORT", when=slShort)
///////////////////////////////////////////////////////////////////////////////
// Testing
plotchar(emaTested, title='emaTested', char='.', color=noColor)
// plot(ma1ishLong, title='ma1ishLong', color=ma1Color, linewidth=1, offset=0)
// plot(ma2ishLong, title='ma2ishLong', color=ma2Color, linewidth=1, offset=0)
// plot(ma3ishLong, title='ma3ishLong', color=ma3Color, linewidth=1, offset=0)
// plot(ma4ishLong, title='ma4ishLong', color=ma4Color, linewidth=1, offset=0)
// plot(ma1ishShort, title='ma1ishShort', color=ma1Color, linewidth=1, offset=0)
// plot(ma2ishShort, title='ma2ishShort', color=ma2Color, linewidth=1, offset=0)
// plot(ma3ishShort, title='ma3ishShort', color=ma3Color, linewidth=1, offset=0)
// plot(ma4ishShort, title='ma4ishShort', color=ma4Color, linewidth=1, offset=0)
Overview
Longs and shorts can be enabled independently and filtered by RSI limits and PMARP signal levels. Date bounds, average lengths and types, and RSI settings are adjustable. It sizes positions as a percentage of equity, recalculates on every tick so signals can change on the live bar, and has no stop loss by default.
The inputs you can change from the gear icon on the chart. Defaults are the author's.
Setting
Type
Default
Variable
Start
time
timestamp('1 Jan 2022 00:00')
startDate
End
time
timestamp('1 Jan 2100 00:00')
endDate
Error Margin For Test (%)
float
10
errorMarginTestInput
Error Margin For Exit (%)
float
10
errorMarginExitInput
includeMA1
bool
true
includeMA1
MA 1
color
#ffeb3b
ma1Color
Length
int
21
ma1Length
Type
string
EMA
ma1Type
includeMA2
bool
true
includeMA2
MA 2
color
#00e676
ma2Color
Length
int
55
ma2Length
Type
string
EMA
ma2Type
Show all 40 settings
Setting
Type
Default
Variable
includeMA3
bool
true
includeMA3
MA 3
color
#00bcd4
ma3Color
Length
int
100
ma3Length
Type
string
EMA
ma3Type
includeMA4
bool
true
includeMA4
MA 4
color
#e040fb
ma4Color
Length
int
200
ma4Length
Type
string
EMA
ma4Type
Longs
bool
true
includeLongs
RSI long limit
float
38
rsiLongLimit
PMARP long signal
float
15
pmarp_long_signal
Shorts
bool
true
includeShorts
RSI short limit
float
62
rsiShortLimit
PMARP short signal
float
85
pmarp_short_signal
RSI Period
int
14
rsiPeriod
Source
source
close
rsiSource
Signal Period
int
12
rsiSignalPeriod
Type
string
EMA
rsiSignalType
Use RSI for SL
bool
true
rsiExits
Bull Control Level
int
62
rsiBullControl
Bear Control Level
int
38
rsiBearControl
Price source
source
close
i_src_price
Lookback
int
350
i_pmarp_lookback
PMAR length
int
20
i_ma_len
MA type...
string
VWMA
i_ma_typ
Use BBWP
bool
false
useBBWP
Above
float
35
bbwpThreshold
Price Source
source
close
i_priceSrc
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.
This mean-reversion strategy combines multi-timeframe exponential moving averages, Bollinger Bands, and the Relative Strength Index. It generates long and optional short trade signals when price interacts with the Bollinger Bands alongside RSI threshold confir
This strategy draws on the price chart and combines Stochastic RSI, the Money Flow Index, and an exponential moving average to open long or short trades. Longs use the lower oscillator thresholds and shorts use the upper ones, with direction limited to longs,
This strategy implements Larry Connors' 2-period RSI mean-reversion algorithm overlaid on the price chart. It filters trades using a long-term Simple Moving Average (SMA), entering long positions when the price trades above the SMA and the short-term RSI drops
This strategy combines multi-timeframe RSI analysis with exponential moving average filters to execute trades on price bounces. It evaluates daily and weekly RSI levels alongside pip-distance thresholds between fast, slow, and long-term EMAs. Position entries
This strategy plots on the price chart and trades fair value gaps filtered by RSI and two EMAs. It opens a long when a bullish gap, a rising candle, RSI below the oversold level, and price under both EMAs align, and a short on the opposite conditions. Each tra
This strategy combines a Simple Moving Average (SMA) and the Relative Strength Index (RSI) to generate long trading signals. It enters a long position when price closes above the SMA filter while RSI drops below the oversold threshold. The strategy exits the p