Pivot Breaks
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © sosso_bott

//@version=5
indicator(title="Pivot Breaks", overlay=true)
import sosso_bott/SAT_LIB/13 as tm

// ——————————————————————————— \\
// ▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼ \\

// ▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲ \\
// ——————————————————————————— \\

no_rep(_symbol, _res, _src) =>
    request.security(_symbol, _res, _src[barstate.isrealtime ? 1:0], barmerge.gaps_off, barmerge.lookahead_off)

resy                            =  input.timeframe(defval="",               title="timeFrame",                                          group="PIVOT H/L")
len                             =  input.int(defval=20,     minval=1,       title="Length",                                             group="PIVOT H/L")
showOnlyFirstSignal             =  input.bool(defval=true,                  title="Use First Break only?",                              group="PIVOT H/L")
color_breakout                  =  input.bool(defval=true,                  title="Color BreakOut BG ?",                                group="PIVOT H/L")
color_state                     =  input.bool(defval=true,                  title="Color Breaking State",                               group="PIVOT H/L")

bullish_break                   = input.color(defval=color.new(color.green, 50),        title="Bull BreakOut",                          group="Colors")
bearish_break                   = input.color(defval=color.new(color.red,   50),        title="Bear BreakOut",                          group="Colors")
bullish                         = input.color(defval=color.new(color.blue,  90),        title="Bull State",                             group="Colors")
bearish                         = input.color(defval=color.new(color.orange,90),        title="Bear State",                             group="Colors")

use_alerts                      = input.bool(defval=true,                               title="Use Alerts",                             group="ALERTS")
bullish_msg                     = input.string(defval="{{exchange}} BUY {{ticker}}",    title="Bull BreakOut Message",                  group="ALERTS")
bearish_msg                     = input.string(defval="{{exchange}} SELL {{ticker}}",   title="Bear BreakOut Message",                  group="ALERTS")

ha_t                            =  syminfo.tickerid
ha_h                            =  no_rep(ha_t, resy, ta.highest(len))
ha_l                            =  no_rep(ha_t, resy, ta.lowest(len))

h1                              =  ta.dev(ha_h, len) ? na : ha_h 
hpivot                          =  fixnan(h1) 
l1                              =  ta.dev(ha_l, len) ? na : ha_l
lpivot                          =  fixnan(l1)


                // ############ QUICK MAGIC ############# \\\
b_p                             =  ta.crossover(close, hpivot)
s_p                             =  ta.crossunder(close, lpivot)
int pivot_state                 = 0
if b_p
    pivot_state := 1
    
if s_p
    pivot_state := -1
    
buy_pivot                       = b_p and pivot_state[1] != pivot_state
sell_pivot                      = s_p and pivot_state[1] != pivot_state
[b_breakout, s_breakout]        = tm.showOnlyFirstOccurence(showOnlyFirstSignal, buy_pivot, sell_pivot)
   
var int break_state = 0
if b_breakout
    break_state := 1
    
if s_breakout
    break_state := -1
                // ############ QUICK MAGIC ############# \\\   
    
                // ############ PLOT ############# \\\
plot(hpivot, color=color.blue, linewidth=2, offset= -len+1)
plot(lpivot, color=color.purple, linewidth=2, offset= -len+1)

plotshape(b_breakout, title="buy",  location=location.belowbar, color=bullish_break, style=shape.triangleup)
plotshape(s_breakout, title="sell", location=location.abovebar, color=bearish_break, style=shape.triangledown)

bgcolor(not color_breakout ? na:    b_breakout          ?   bullish_break   :   s_breakout          ? bearish_break   :   na)
bgcolor(not color_state    ? na:    break_state == 1    ?   bullish         :   break_state == -1   ? bearish         :   na)
                // ############ PLOT ############# \\\
                
                
                // ############ ALERTS ############# \\\
if use_alerts

    if b_breakout
        alert(bullish_msg, alert.freq_once_per_bar_close)
        
    if s_breakout
        alert(bearish_msg, alert.freq_once_per_bar_close)
                // ############ ALERTS ############# \\\
