// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.
0
International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// © LuxAlgo
//@version=5
indicator("Reversal Candlestick Structure [LuxAlgo]",shorttitle = "LuxAlgo -
Reversal Candlestick Structure", overlay = true, max_labels_count = 500,
max_lines_count = 500)
//---------------------------------------------------------------------------------
------------------------------------}
//Tooltips
//---------------------------------------------------------------------------------
------------------------------------{
hammer_tt = "The Hammer pattern appears at the bottom of a downtrend. It is
identified by a small upper wick (or no upper wick) with a small body, and an
elongated lower wick whose length is 2X greater than the candle body’s width."
ihammer_tt = "The Inverted Hammer pattern appears at the bottom of a downtrend.
It is identified by a small lower wick (or no lower wick) with a small body, and an
elongated upper wick whose length is 2X greater than the candle body’s width."
hman_tt = "The Hanging Man pattern appears at the top of an uptrend. It is
identified by a small upper wick (or no upper wick) with a small body, and an
elongated lower wick whose length is 2X greater than the candle body’s width."
sstar_tt = "The Shooting Star pattern appears at the top of an uptrend. It is
identified by a small lower wick (or no lower wick) with a small body, and an
elongated upper wick whose length is 2X greater than the candle body’s width."
bulle_tt = "The Bullish Engulfing pattern appear at the bottom of a
downtrend. It is a 2 bar pattern, identified by a large bullish candle body fully
encapsulating (opening lower and closing higher) the previous small (bearish)
candle body."
beare_tt = "The Bearish Engulfing pattern appears at the top of a downtrend.
It is a 2 bar pattern, identified by a large bearish candle body fully
encapsulating (opening higher and closing lower) the previous small (bullish)
candle body."
r3_tt = "The Rising Three Method Pattern is an indicator of continuation
for the current trend. It is a 5 bar pattern, identified by an initial full-bodied
bullish candle, followed by 3 bearish candles that trade within the high and low of
the initial candle, followed by another full-bodied bullish candle closing above
the high of the initial candle."
f3_tt = "The Falling Three Method Pattern is an indicator of continuation
for the current trend. It is a 5 bar pattern, identified by an initial full-bodied
bearish candle, followed by 3 bullish candles that trade within the high and low of
the initial candle, followed by another full-bodied bearish candle closing below
the low of the initial candle."
tws_tt = "The Three White Soldiers Pattern appears at the bottom of a
downtrend. It is identified by 3 full-bodied bullish candles, each opening within
the body and closing below the high, of the previous candle."
tbc_tt = "The Three Black Crows Pattern appears at the top of an uptrend.
It is identified by 3 full-bodied bearish candles, each open within the body and
closing below the low, of the previous candle."
mstar_tt = "The Morning Star Pattern appears at the bottom of a downtrend. It
is a 3 bar pattern, identified by a full-bodied bearish candle, followed by a
small-bodied bearish candle, followed by a full-bodied bullish candle that closes
above the halfway point of the first candle."
estar_tt = "The Evening Star Pattern appears at the top of an uptrend. It is
a 3 bar pattern, identified by a full-bodied bullish candle, followed by a small-
bodied bullish candle, followed by a full-bodied bearish candle that closes below
the halfway point of the first candle."
bullh_tt = "The Bullish Harami Pattern appears at the bottom of a downtrend.
It is a 2 bar pattern, identified by an initial bearish candle, followed by a small
bullish candle whose range is entirely contained within the body of the initial
candle."
bearh_tt = "The Bearish Harami Pattern appears at the top of an uptrend. It
is a 2 bar pattern, identified by an initial bullish candle, followed by a small
bearish candle whose range is entirely contained within the body of the initial
candle."
tweezer_top_tt = "The Tweezer Top bearish reversal candlestick pattern is
identified by an initial bullish candle, followed by a bearish candle, both having
equal highs."
tweezer_btm_tt = "The Tweezer Bottom bullish reversal candlestick pattern is
identified by an initial bullish candle, followed by a bearish candle, both having
equal lows."
//---------------------------------------------------------------------------------
------------------------------------}
//User Inputs
//---------------------------------------------------------------------------------
------------------------------------{
group1 = " Bullish Patterns Bearish Patterns"
//Bullish
hammerTog = input.bool(true, "Hammer ", group = group1, inline = "1")
ihammerTog = input.bool(true, "Inverted Hammer ", group = group1, inline = "2")
bulleTog = input.bool(true, "Bullish Engulfing ", group = group1, inline =
"3")
r3Tog = input.bool(true, "Rising 3 ", group = group1, inline =
"4")
twsTog = input.bool(true, "3 White Soldiers ", group = group1, inline =
"5")
mstarTog = input.bool(true, "Morning Star ", group = group1, inline =
"6")
bullhTog = input.bool(true, "Bullish Harami ", group = group1, inline = "7")
btmTweezTog = input.bool(true, "Tweezer Bottom ", group = group1, inline = "8")
//Bearish
hmanTog = input.bool(true, "Hanging Man", group = group1, inline = "1")
sstarTog = input.bool(true, "Shooting Star", group = group1, inline = "2")
beareTog = input.bool(true, "Bearish Engulfing", group = group1, inline = "3")
f3Tog = input.bool(true, "Falling 3", group = group1, inline = "4")
tbcTog = input.bool(true, "3 Black Crows", group = group1, inline = "5")
estarTog = input.bool(true, "Evening Star", group = group1, inline = "6")
bearhTog = input.bool(true, "Bearish Harami", group = group1, inline = "7")
topTweezTog = input.bool(true, "Tweezer Top", group = group1, inline = "8")
//Trend
length = input.int(14, 'Trend Length', minval = 2, group = 'Reversal Detection')
threshold = input.float(80, 'Threshold', minval = 0, maxval = 100, group =
'Reversal Detection')
smooth = input.float(20, 'Warmup Length', minval = 1, group = 'Reversal Detection')
//Style
bcTog = input.bool(true, title = "Color Candles", group = "Style", tooltip = "Color
Candles to visualize minor trend.")
bullColor = input.color(#089981, title = "Bull Color ", group = "Style")
bearColor = input.color(#f23645, title = "Bear Color", group = "Style")
useGradient = input.bool(true, title = "Use Gradient", group = "Style")
txtSize = input.string("tiny", title = "Label Size", options =
["tiny","small","normal","large","huge","auto"], group = "Style", inline = "3")
//Dashboard
showDash = input.bool(false, 'Show Dashboard', group = 'Dashboard')
dashLoc = input.string('Bottom Right' , 'Location' , options = ['Top Right',
'Bottom Right', 'Bottom Left'] , group = 'Dashboard')
textSize = str.lower( input.string('Tiny', 'Size', options = ['Tiny', 'Small',
'Normal'], group = 'Dashboard') )
//---------------------------------------------------------------------------------
------------------------------------}
//Functions
//---------------------------------------------------------------------------------
------------------------------------{
count(condition, filter)=>
var reversals = 0
var total = 0
reversals += condition and filter ? 1 : 0
total += condition ? 1 : 0
[condition and filter, reversals / total * 100, total]
//---------------------------------------------------------------------------------
------------------------------------}
//Trend Detection
//---------------------------------------------------------------------------------
------------------------------------{
var smooth_k = 0.
var alpha = 2./(smooth+1)
k = ta.stoch(close, close, close, length)
alpha := 2/(smooth+1)
smooth_k := k > 50 ? smooth_k + nz(100 - smooth_k) * alpha : k < 50 ? smooth_k +
nz(0 - smooth_k) * alpha : nz(k)
is_bullish = k >= threshold and smooth_k >= threshold
is_bearish = k <= 100 - threshold and smooth_k <= 100 - threshold
//---------------------------------------------------------------------------------
------------------------------------}
//Candestick Patterns
//---------------------------------------------------------------------------------
------------------------------------{
rc = close < open // Red Candle
gc = close > open // Green Candle
//Candle measurements
c_top = math.max(open,close) //Top of candle
c_bot = math.min(open,close) //Bottom of candle
hl_width = high - low //Total candle width (wick to wick)
bod_width = (c_top - c_bot) //Width of candle body (open to close)
hw_per = ((high - c_top) / hl_width) * 100 //Percent of total candle width that is
occupied by the upper wick
lw_per = ((c_bot - low) / hl_width) * 100 //Percent of total candle width that is
occupied by the lower wick
b_per = (bod_width / hl_width) * 100 //Percent of total candle width that is
occupied by the candle body
doji = math.round_to_mintick(close) == math.round_to_mintick(open)
//Bullish patterns
[hammer, hammer_per, hammer_count] = count((lw_per > (b_per*2) and b_per < 50 and
hw_per < 2 and not doji), is_bearish)
[inv_hammer, inv_hammer_per, inv_hammer_count] = count((hw_per > (b_per*2) and
b_per < 50 and lw_per < 2 and not doji), is_bearish)
[rising_3, rising_3_per, rising_3_count] = count(
(gc[4] and b_per[4] > 50)
and (rc[3] and c_top[3] <= high[4] and c_bot[3] >= low[4])
and (rc[2] and c_top[2] <= high[4] and c_bot[2] >= low[4])
and (rc[1] and c_top[1] <= high[4] and c_bot[1] >= low[4])
and (gc and close > high[4] and b_per > 50),
is_bearish[1])
[bull_engulfing, bull_engulfing_per, bull_engulfing_count] = count(
rc[1] and gc and (bod_width > (bod_width[1]/2)) and (open < close[1]) and c_top >
c_top[1] and (not rising_3) and (not doji[1]),
is_bearish[1])
[soldiers, soldiers_per, soldiers_count] = count(
(gc[2] and b_per[2]>70)
and (gc[1] and b_per[1]>70 and c_bot[1] >= c_bot[2] and c_bot[1] <= c_top[2] and
close[1] > high[2])
and (gc and b_per>70 and c_bot >= c_bot[1] and c_bot <= c_top[1] and close >
high[1]),
is_bearish[3])
[m_star, m_star_per, m_star_count] = count(
(rc[2] and b_per[2] > 80)
and (rc[1] and bod_width[1] < (bod_width[2]/2) and open[1] < close[2])
and (gc and close > hl2[2]),
is_bearish)
[bull_harami, bull_harami_per, bull_harami_count] = count(
gc and (high <= c_top[1] and low >= c_bot[1]) and rc[1],
is_bearish)
[tweezer_btm, tweezer_btm_per, tweezer_btm_count] = count(
math.round_to_mintick(low) - math.round_to_mintick(low[1]) == 0 and gc and rc[1],
is_bearish[1])
// Bearish patterns
[s_star, s_star_per, s_star_count] = count(
(hw_per > (b_per*2) and b_per < 50 and lw_per < 2 and not doji),
is_bullish)
[h_man, h_man_per, h_man_count] = count(
(lw_per > (b_per*2) and b_per < 50 and hw_per < 2 and not doji),
is_bullish)
[falling_3, falling_3_per, falling_3_count] = count(
(rc[4] and b_per[4] > 50)
and (gc[3] and c_top[3] <= high[4] and c_bot[3] >= low[4])
and (gc[2] and c_top[2] <= high[4] and c_bot[2] >= low[4])
and (gc[1] and c_top[1] <= high[4] and c_bot[1] >= low[4])
and (rc and close < low[4] and b_per > 50),
is_bullish[1])
[bear_engulfing, bear_engulfing_per, bear_engulfing_count] = count(
gc[1] and rc and (bod_width > (bod_width[1]/2)) and (open > close[1]) and c_bot <
c_bot[1] and (not falling_3) and (not doji[1]),
is_bullish[1])
[crows, crows_per, crows_count] = count(
(rc[2] and b_per[2]>70)
and (rc[1] and b_per[1]>70 and c_top[1] <= c_top[2] and c_top[1] >= c_bot[2] and
close[1] < low[2])
and (rc and b_per>70 and c_top <= c_top[1] and c_top >= c_bot[1] and close <
low[1]),
is_bullish[3])
[e_star, e_star_per, e_star_count] = count(
(gc[2] and b_per[2] > 80)
and (gc[1] and bod_width[1] < (bod_width[2]/2) and open[1] > close[2])
and (rc and close < hl2[2]),
is_bullish)
[bear_harami, bear_harami_per, bear_harami_count] = count(
rc and (high <= c_top[1] and low >= c_bot[1]) and gc[1],
is_bullish)
[tweezer_top, tweezer_top_per, tweezer_top_count] = count(
math.round_to_mintick(high) - math.round_to_mintick(high[1]) == 0 and rc and
gc[1],
is_bullish[1])
//---------------------------------------------------------------------------------
------------------------------------}
//Labels
//---------------------------------------------------------------------------------
------------------------------------{
//Bullish patterns
if hammer and hammerTog
label.new(bar_index,low,"H", color = color(na), style = label.style_label_up,
textcolor = bullColor, size = txtSize, tooltip = hammer_tt)
if inv_hammer and ihammerTog
label.new(bar_index,low,"IH", color = color(na), style = label.style_label_up,
textcolor = bullColor, size = txtSize, tooltip = ihammer_tt)
if s_star and sstarTog
label.new(bar_index,high,"SS", color = color(na), style =
label.style_label_down, textcolor = bearColor, size = txtSize, tooltip = sstar_tt)
if h_man and hmanTog
label.new(bar_index,high,"HM", color = color(na), style =
label.style_label_down, textcolor = bearColor, size = txtSize, tooltip = hman_tt)
if rising_3 and r3Tog
label.new(bar_index,low,"R3", color = color(na), style = label.style_label_up,
textcolor = bullColor, size = txtSize, tooltip = r3_tt)
if falling_3 and f3Tog
label.new(bar_index,high,"F3", color = color(na), style =
label.style_label_down, textcolor = bearColor, size = txtSize, tooltip = f3_tt)
if bull_engulfing and bulleTog
label.new(bar_index,low,"EG▲", color = color(na), style = label.style_label_up,
textcolor = bullColor, size = txtSize, tooltip = bulle_tt)
if bull_engulfing and bulleTog
label.new(bar_index,low,"EG▲", color = color(na), style = label.style_label_up,
textcolor = bullColor, size = txtSize, tooltip = bulle_tt)
if tweezer_btm and btmTweezTog
label.new(bar_index,low,"TB", color = color(na), style = label.style_label_up,
textcolor = bullColor, size = txtSize, tooltip = tweezer_btm_tt)
//Bearish patterns
if bear_engulfing and beareTog
label.new(bar_index,high,"EG▼", color = color(na), style =
label.style_label_down, textcolor = bearColor, size = txtSize, tooltip = beare_tt)
if soldiers and twsTog
label.new(bar_index,low,"3WS", color = color(na), style = label.style_label_up,
textcolor = bullColor, size = txtSize, tooltip = tws_tt)
if crows and tbcTog
label.new(bar_index,high,"3BC", color = color(na), style =
label.style_label_down, textcolor = bearColor, size = txtSize, tooltip = tbc_tt)
if m_star and mstarTog
label.new(bar_index,low,"MS", color = color(na), style = label.style_label_up,
textcolor = bullColor, size = txtSize, tooltip = mstar_tt)
if e_star and estarTog
label.new(bar_index,high,"ES", color = color(na), style =
label.style_label_down, textcolor = bearColor, size = txtSize, tooltip = estar_tt)
if bull_harami and bullhTog
label.new(bar_index,low,"H▲", color = color(na), style = label.style_label_up,
textcolor = bullColor, size = txtSize, tooltip = bullh_tt)
if bear_harami and bearhTog
label.new(bar_index,high,"H▼", color = color(na), style =
label.style_label_down, textcolor = bearColor, size = txtSize, tooltip = bearh_tt)
if tweezer_top and topTweezTog
label.new(bar_index,high,"TT", color = color(na), style =
label.style_label_down, textcolor = bearColor, size = txtSize, tooltip =
tweezer_top_tt)
//---------------------------------------------------------------------------------
------------------------------------}
//Table
//---------------------------------------------------------------------------------
------------------------------------{
var table_position = dashLoc == 'Bottom Left' ? position.bottom_left
: dashLoc == 'Top Right' ? position.top_right
: position.bottom_right
var t = table.new(table_position, 4, 10
, bgcolor = #1e222d
, border_color = #373a46
, border_width = 1
, frame_color = #373a46
, frame_width = 1)
//Table setup
if showDash
t.merge_cells(0,0,1,0)
t.merge_cells(2,0,3,0)
if barstate.islast and showDash
//Titles
t.cell(0,0, "Bullish", text_color = color.white, bgcolor =
color.new(bullColor,50), text_size = textSize)
t.cell(2,0, "Bearish", text_color = color.white, bgcolor =
color.new(bearColor,50), text_size = textSize)
t.cell(0,1, "Pattern", text_color = color.white, text_size = textSize)
t.cell(1,1, "Reversals %", text_color = color.white, text_size = textSize)
t.cell(2,1, "Pattern", text_color = color.white, text_size = textSize)
t.cell(3,1, "Reversals %", text_color = color.white, text_size = textSize)
// Bullish Stats
if hammerTog
t.cell(0,2, "Hammer (H)", text_halign = text.align_left, text_color =
color.white, text_size = textSize)
t.cell(1,2, str.tostring(nz(hammer_per), format.percent), tooltip =
"Pattern Count:" + str.tostring(hammer_count), text_color = color.white, text_size
= textSize)
if ihammerTog
t.cell(0,3, "Inverted Hammer (IH)", text_halign = text.align_left,
text_color = color.white, text_size = textSize)
t.cell(1,3, str.tostring(nz(inv_hammer_per), format.percent), tooltip =
"Pattern Count:" + str.tostring(inv_hammer_count), text_color = color.white,
text_size = textSize)
if bulleTog
t.cell(0,4, "Bullish Engulfing (EG▲)", text_halign = text.align_left,
text_color = color.white, text_size = textSize)
t.cell(1,4, str.tostring(nz(bull_engulfing_per), format.percent), tooltip =
"Pattern Count:" + str.tostring(bull_engulfing_count), text_color = color.white,
text_size = textSize)
if r3Tog
t.cell(0,5, "Rising 3 (R3)", text_halign = text.align_left, text_color =
color.white, text_size = textSize)
t.cell(1,5, str.tostring(nz(rising_3_per), format.percent), tooltip =
"Pattern Count:" + str.tostring(rising_3_count), text_color = color.white,
text_size = textSize)
if twsTog
t.cell(0,6, "3 White Soldiers (3WS)", text_halign = text.align_left,
text_color = color.white, text_size = textSize)
t.cell(1,6, str.tostring(nz(soldiers_per), format.percent), tooltip =
"Pattern Count:" + str.tostring(soldiers_count), text_color = color.white,
text_size = textSize)
if mstarTog
t.cell(0,7, "Morning Star (MS)", text_halign = text.align_left, text_color
= color.white, text_size = textSize)
t.cell(1,7, str.tostring(nz(m_star_per), format.percent), tooltip =
"Pattern Count:" + str.tostring(m_star_count), text_color = color.white, text_size
= textSize)
if bullhTog
t.cell(0,8, "Bull Harami (H▲)", text_halign = text.align_left, text_color
= color.white, text_size = textSize)
t.cell(1,8, str.tostring(nz(bull_harami_per), format.percent), tooltip =
"Pattern Count:" + str.tostring(bull_harami_count), text_color = color.white,
text_size = textSize)
if btmTweezTog
t.cell(0,9, "Tweezer Bottom (TB)", text_halign = text.align_left,
text_color = color.white, text_size = textSize)
t.cell(1,9, str.tostring(nz(tweezer_btm_per), format.percent), tooltip =
"Pattern Count:" + str.tostring(tweezer_btm_count), text_color = color.white,
text_size = textSize)
// Bearish Stats
if hmanTog
t.cell(2,2, "Hanging Man (HM)", text_halign = text.align_left, text_color
= color.white, text_size = textSize)
t.cell(3,2, str.tostring(nz(h_man_per), format.percent), tooltip = "Pattern
Count:" + str.tostring(h_man_count), text_color = color.white, text_size =
textSize)
if sstarTog
t.cell(2,3, "Shooting Star (SS)", text_halign = text.align_left,
text_color = color.white, text_size = textSize)
t.cell(3,3, str.tostring(nz(s_star_per), format.percent), tooltip =
"Pattern Count:" + str.tostring(s_star_count), text_color = color.white, text_size
= textSize)
if beareTog
t.cell(2,4, "Bear Engulfing (EG▼)", text_halign = text.align_left,
text_color = color.white, text_size = textSize)
t.cell(3,4, str.tostring(nz(bear_engulfing_per), format.percent), tooltip =
"Pattern Count:" + str.tostring(bear_engulfing_count), text_color = color.white,
text_size = textSize)
if f3Tog
t.cell(2,5, "Falling 3 (F3)", text_halign = text.align_left, text_color =
color.white, text_size = textSize)
t.cell(3,5, str.tostring(nz(falling_3_per), format.percent), tooltip =
"Pattern Count:" + str.tostring(falling_3_count), text_color = color.white,
text_size = textSize)
if tbcTog
t.cell(2,6, "3 Black Crows (3BC)", text_halign = text.align_left,
text_color = color.white, text_size = textSize)
t.cell(3,6, str.tostring(nz(crows_per), format.percent), tooltip = "Pattern
Count:" + str.tostring(crows_count), text_color = color.white, text_size =
textSize)
if estarTog
t.cell(2,7, "Evening Star (ES)", text_halign = text.align_left, text_color
= color.white, text_size = textSize)
t.cell(3,7, str.tostring(nz(e_star_per), format.percent), tooltip =
"Pattern Count:" + str.tostring(e_star_count), text_color = color.white, text_size
= textSize)
if bearhTog
t.cell(2,8, "Bear Harami (H▼)", text_halign = text.align_left, text_color
= color.white, text_size = textSize)
t.cell(3,8, str.tostring(nz(bear_harami_per), format.percent), tooltip =
"Pattern Count:" + str.tostring(bear_harami_count), text_color = color.white,
text_size = textSize)
if topTweezTog
t.cell(2,9, "Tweezer Top (TT)", text_halign = text.align_left, text_color
= color.white, text_size = textSize)
t.cell(3,9, str.tostring(nz(tweezer_top_per), format.percent), tooltip =
"Pattern Count:" + str.tostring(tweezer_top_count), text_color = color.white,
text_size = textSize)
//---------------------------------------------------------------------------------
------------------------------------}
//Candle Coloring
//---------------------------------------------------------------------------------
------------------------------------{
var color css = na
if bcTog
if useGradient
css := switch
is_bullish => color.from_gradient(smooth_k, threshold, 100,
color.new(bearColor, 80), bearColor)
is_bearish => color.from_gradient(smooth_k, 0, 100 - threshold,
bullColor, color.new(bullColor, 80))
=> na
else
css := is_bullish ? bearColor : is_bearish ? bullColor : na
barcolor(css, title = 'Candle Coloring')
//---------------------------------------------------------------------------------
------------------------------------}