Flat & Trend MACD
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Shuttle_Trader
//@version=5

indicator(title='Flat & Trend MACD', shorttitle='Flat & Trend MACD', overlay=true)

fast_length = input(title='Fast Length', defval=20)
slow_length = input(title='Slow Length', defval=100)
signal_length = input.int(title='Signal Smoothing', minval=1, maxval=50, defval=10)
show_flat = input.bool(true, title='Show flat zones')

//  Price channel
hline = ta.highest(fast_length)
lline = ta.lowest(fast_length)

//  MACD setup
[macd, signal, hist] = ta.macd(close, fast_length, slow_length, signal_length)

//  MACD flat
flat_value = math.max(ta.highest(hist,50), math.abs(ta.lowest(hist,50)))/2

//  MACD trend
buyzone = bool(na), sellzone = bool(na)
buyzone := hist > 0 and math.abs(hist) > flat_value
sellzone := hist < 0 and math.abs(hist) > flat_value

if not buyzone and not sellzone
    buyzone := buyzone[1]
    sellzone := sellzone[1]

MACD_trend = 0
MACD_trend := buyzone ? 1 : sellzone ? -1 : nz(MACD_trend[1])

//  Plot colors

trend_color = color(na)

if show_flat
    trend_color := 
     MACD_trend>0 and math.abs(hist) > flat_value ? color.rgb(12, 100, 14, 60) : 
     MACD_trend>0 and math.abs(hist) < flat_value ? color.rgb(133, 153, 133, 80) : 
     MACD_trend<0 and math.abs(hist) > flat_value ? color.rgb(138, 24, 24, 60) : 
     MACD_trend<0 and math.abs(hist) < flat_value ? color.rgb(153, 134, 134, 80) : na

if not show_flat
    trend_color := 
     MACD_trend>0 ? color.rgb(12, 100, 14, 60) : 
     MACD_trend<0 ? color.rgb(138, 24, 24, 60) : na
    
hl = plot(hline, title='High-line', color=color.rgb(12, 100, 14, 30))
ll = plot(lline, title='Low-line', color=color.rgb(138, 24, 24, 30))

fill(hl, ll, color=trend_color, fillgaps=true)

plotshape(MACD_trend>0 and MACD_trend[1]<=0, title='UP', style=shape.triangleup, location=location.belowbar, color=#08f108, text='', textcolor=#08f108, size=size.tiny)
plotshape(MACD_trend<0 and MACD_trend[1]>=0, title='DN', style=shape.triangledown, location=location.abovebar, color=#ee0e3f, text='', textcolor=#ee0e3f, size=size.tiny)

//  Beginning flat
flat_up = math.abs(hist)<flat_value and (math.abs(hist)>flat_value)[1] and MACD_trend>0
flat_dn = math.abs(hist)<flat_value and (math.abs(hist)>flat_value)[1] and MACD_trend<0

plotshape(show_flat ? flat_up : na, title='flat up', style=shape.square, location=location.belowbar, color=#cc6e16, text='', textcolor=#08f108, size=size.tiny)
plotshape(show_flat ? flat_dn : na, title='flat dn', style=shape.square, location=location.belowbar, color=#cc6e16, text='', textcolor=#08f108, size=size.tiny)

//  Alerts

if MACD_trend>0 and MACD_trend[1]<=0
    alert('🟢 '+ syminfo.ticker + '  >> MACD UP-TREND',alert.freq_once_per_bar_close)
if MACD_trend<0 and MACD_trend[1]>=0
    alert('🔴 '+ syminfo.ticker + '  >> MACD DOWN-TREND',alert.freq_once_per_bar_close)

if flat_up
    alert('⚠️ '+ syminfo.ticker + '  >> MACD Flat zone in UP-TREND',alert.freq_once_per_bar_close)
if flat_dn
    alert('⚠️ '+ syminfo.ticker + '  >> MACD Flat zone in DOWN-TREND',alert.freq_once_per_bar_close)

ST00 = '>>>  Flat & Trend MACD  <<<\n\n' + syminfo.tickerid + '   tf = ' + timeframe.period
ST01 = 'MACD TREND : ' + (MACD_trend>0 ? 'LONG' : MACD_trend<0 ? 'SHORT' : '') + (math.abs(hist)<flat_value ? '\n⚠️ Flat zone!' : '')
var table state = table.new(position = position.top_right, columns=1, rows=2, border_color = color.new(#035509, 0), border_width = 1, frame_color = color.new(#035509,0), frame_width = 2)
table.cell(state, 0, 0, ST00, text_color=color.new(#000000,0), text_size = size.normal, bgcolor = color.new(#388e3c,0))
table.cell(state, 0, 1, ST01, text_color=color.new(#000000,0), text_size = size.normal, bgcolor = color.new(#388e3c,0))
