// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.
0
International (CC BY-NC-SA 4.0) [Link]
// © LuxAlgo
//@version=5
indicator( 'Swing Breakouts Tests & Retests [LuxAlgo]', shorttitle='LuxAlgo -
Swing Breakouts Tests & Retests', max_labels_count=500, max_boxes_count=500,
overlay=true)
//--------------------------------------------------------------------------------
-------------------------------------}
// Settings
//--------------------------------------------------------------------------------
-------------------------------------{
display = [Link]('Bullish AND Bearish', 'Display' , options=['Bullish
OR Bearish', 'Bullish AND Bearish', 'Bearish', 'Bullish'])
mult = [Link] (1 , 'Width' , step =0.1
)
maxBars = [Link] (500 , 'Maximum Bars' , tooltip=
'Maximum bars without signal' )
showReTest = [Link]('All', 'Display Test/Retest Labels' , options=
['All', 'Last'] )
minBars = [Link] (0 , 'Minimum Bars' , minval =0,
tooltip= 'Minimum required amount of bars between each labels')
setBack = [Link] (true, 'Set Back To Last Retest' , tooltip='When the
right side of the area is too far, stop updating and set back to position of last
test/retest')
left = [Link] (10 , 'Left' , minval =1,
group='Swings'), right = [Link] (1, 'Right' , minval =1 , group
='Swings' )
//Style
bull1_color = [Link] (#08998145, 'Bullish ' , inline = 'bull' ,
group= 'Style' )
bull2_color = [Link] (#f2364545, '' , inline = 'bull' ,
group= 'Style' )
bear1_color = [Link] (#f2364545, 'Bearish' , inline = 'bear' ,
group= 'Style' )
bear2_color = [Link] (#08998145, '' , inline = 'bear' ,
group= 'Style' )
labSize = [Link]([Link] , 'Label Size' ,
options=[[Link], [Link], [Link], [Link]] )
//--------------------------------------------------------------------------------
-------------------------------------}
//UDT
//--------------------------------------------------------------------------------
-------------------------------------{
// @type bin object
// @field bx box, breakout and retest
// @field state holds the current state
// @field price holds highest/lowest price
// @field lab1 array of labels (re-test)
// @field lab2 array of labels (re-test)
type bin
box bx
int state
float price
array<label>lab1
array<label>lab2
//--------------------------------------------------------------------------------
-------------------------------------}
//Methods
//--------------------------------------------------------------------------------
-------------------------------------{
n = bar_index
// @function Fetches the red, green and blue value from the input
// @param col color
// @returns [Link]() without transparancy
method colorRGB(color col) =>
[Link](
color.r(col)
, color.g(col)
, color.b(col)
)
// @function controls whether a label may be added to array
// @param aLab array (receiver)
// @returns bool - true/false
method mayAdd(array<label>aLab) => [Link]() == 0 or showReTest == 'Last' ? true
: showReTest == 'All' and n - [Link]().get_x() > minBars
// @function Provides a label
// @param dir bullish 'bull' or bearish 'bear'
// @param state concerning state (1 or 2)
// @returns label
method label(string dir, int state, float y) =>
lab = [Link](n, y, color= color(na), size=labSize)
switch dir
'bull' =>
switch state
1 => lab.set_style(label.style_label_up ), lab.set_text('▲'),
lab.set_textcolor(bull1_color.colorRGB())
2 => lab.set_style(label.style_label_down), lab.set_text('▽'),
lab.set_textcolor(bull2_color.colorRGB())
'bear' =>
switch state
1 => lab.set_style(label.style_label_down), lab.set_text('▼'),
lab.set_textcolor(bear1_color.colorRGB())
2 => lab.set_style(label.style_label_up ), lab.set_text('△'),
lab.set_textcolor(bear2_color.colorRGB())
lab
// @function Adds label to array, pops 1 out if 'onlyLast'
// @param aLab array (receiver)
// @param lab lab to add
// @returns void or label
method addLabel(array<label>aLab, label lab) =>
[Link](lab)
if showReTest == 'Last'
and [Link]() > 1
[Link]()
//--------------------------------------------------------------------------------
-------------------------------------}
//Variables
//--------------------------------------------------------------------------------
-------------------------------------{
var bull = [Link](box(na), 0, na, [Link]<label>(), [Link]<label>())
var bear = [Link](box(na), 0, na, [Link]<label>(), [Link]<label>())
//--------------------------------------------------------------------------------
-------------------------------------}
//Execution
//--------------------------------------------------------------------------------
-------------------------------------{
atr = nz([Link](200), [Link](high - low) / (n + 1)) * mult
ph = [Link](left, right)
pl = [Link] (left, right)
box_bull_left = [Link].get_left ()
box_bull_right = [Link].get_right ()
box_bull_top = [Link].get_top ()
box_bull_bottom = [Link].get_bottom()
box_bear_left = [Link].get_left ()
box_bear_right = [Link].get_right ()
box_bear_top = [Link].get_top ()
box_bear_bottom = [Link].get_bottom()
//Bullish
if display == 'Bullish'
or display == 'Bullish AND Bearish'
or (display == 'Bullish OR Bearish'
and [Link] == 0
)
switch
[Link] == 0 =>
if not na(pl)
[Link] := [Link](n - right, pl + atr, n, pl,
bgcolor=bull1_color, border_color=color(na))
[Link] := 1 //Swing found; if condition is ok - state 0 -> 1
[Link]() //chuck labels out of array without deleting
[Link]()
[Link] := pl
[Link] == 1 =>
if box_bull_right - box_bull_left >= maxBars //Right side is too far
from start
if [Link]() == 0
[Link]()
else
if setBack
[Link].set_right([Link]().get_x())
[Link] := 0 //Reset
else
[Link].set_right(n)
//Breakout; first box remains, switch to second box - state 1 -> 2
if close < box_bull_bottom
[Link] := [Link](n, box_bull_top, n, box_bull_bottom,
bgcolor=bull2_color, border_color=color(na))
[Link] := 2
[Link] := box_bull_top
if close > box_bull_top and open < box_bull_top and
[Link]()
[Link]('bull'.label(1, [Link])).delete()
[Link] == 2 =>
if box_bull_right - box_bull_left >= maxBars
if [Link]() == 0
[Link]()
else
if setBack
[Link].set_right([Link]().get_x())
[Link] := 0
else
[Link].set_right(n)
if close > box_bull_top
[Link] := 0 //Reset
if close < box_bull_bottom and open > box_bull_bottom and
[Link]()
[Link]('bull'.label(2, [Link])).delete()
//Bearish
if display == 'Bearish'
or display == 'Bullish AND Bearish'
or (display == 'Bullish OR Bearish'
and [Link] == 0
)
switch
[Link] == 0 =>
if not na(ph)
[Link] := [Link](n - right, ph, n, ph - atr,
bgcolor=bear1_color, border_color=color(na))
[Link] := 1
[Link]() //chuck labels out of array without deleting
[Link]()
[Link] := ph
[Link] == 1 =>
if box_bear_right - box_bear_left >= maxBars
if [Link]() == 0
[Link]()
else
if setBack
[Link].set_right([Link]().get_x())
[Link] := 0
else
[Link].set_right(n)
if close > box_bear_top
[Link] := [Link](n, box_bear_top, n, box_bear_bottom,
bgcolor=bear2_color, border_color=color(na))
[Link] := 2
[Link] := box_bear_bottom
if close < box_bear_bottom and open > box_bear_bottom and
[Link]()
[Link]('bear'.label(1, [Link])).delete()
[Link] == 2 =>
if box_bear_right - box_bear_left >= maxBars
if [Link]() == 0
[Link]()
else
if setBack
[Link].set_right([Link]().get_x())
[Link] := 0
else
[Link].set_right(n)
if close < box_bear_bottom
[Link] := 0
if close > box_bear_top and open < box_bear_top and
[Link]()
[Link]('bear'.label(2, [Link])).delete()
//--------------------------------------------------------------------------------
-------------------------------------}