Flat Detect By Bollinger Bands
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Eff_Hash

//@version=5
indicator(shorttitle="Flat Detect By BB", title="Flat Detect By Bollinger Bands", overlay=true, timeframe="", timeframe_gaps=true)

//Inputs
BBlength = input.int(20, minval=1, group='Bollinger Bands Config')
BBsrc = input(close, title="Source", group='Bollinger Bands Config')
BBmult = input.float(2.0, minval=0.001, maxval=50, title="StdDev", group='Bollinger Bands Config')
BBThreshold_Type = input.string(title="Threshold Type", defval="Ticks", options=["Ticks", "%"], group='Bollinger Bands Config')
BBThreshold_Width = input.float(0.055, minval=0, step=0.001, title="Threshold Width in Ticks (Old version)", group='Bollinger Bands Config')
BBThreshold_Width_purcent = input.float(1.00, minval=0, step=0.1, title="Threshold Width in %", group='Bollinger Bands Config')

Add_ATR_Filter = input.bool(title = 'Add ATR Filter', defval=false, group='ATR Config')
ATR_length = input.int(title="Length", defval=14, minval=1, group='ATR Config')
ATR_smoothing = input.string(title="Smoothing", defval="RMA", options=["RMA", "SMA", "EMA", "WMA"], group='ATR Config')
ATR_Threshold = input.float(minval=0.0, defval=25, title="ATR Threshold", group='ATR Config')

//ATR Calcul
ATR_ma_function(source, ATR_length) =>
	switch ATR_smoothing
		"RMA" => ta.rma(source, ATR_length)
		"SMA" => ta.sma(source, ATR_length)
		"EMA" => ta.ema(source, ATR_length)
		=> ta.wma(source, ATR_length)

ATR_signal = ATR_ma_function(ta.tr(true), ATR_length)
ATR_no_trade = Add_ATR_Filter ? (ATR_signal <= ATR_Threshold) : false
ATR_go_trade = not ATR_no_trade

//Bollinger Bands & Width calcul
BBdev = BBmult * ta.stdev(BBsrc, BBlength)
BBbasis = ta.sma(BBsrc, BBlength)
BBupper = BBbasis + BBdev
BBlower = BBbasis - BBdev
bbw = (BBupper-BBlower)/BBbasis
bbw_purcent = (BBupper-BBlower) / BBupper * 100

//Flat Zone color change
BBcolor = color.white
BackBBcolor = color.white

//In %
if BBThreshold_Type == "%"
	BBcolor := (bbw_purcent > BBThreshold_Width_purcent) and ATR_go_trade ? color.lime : color.red
	BackBBcolor := (bbw_purcent > BBThreshold_Width_purcent) and ATR_go_trade ? color.rgb(33, 250, 243, 90) : color.rgb(250, 5, 10, 90)

//In Ticks
if BBThreshold_Type == "Ticks"
	BBcolor := (bbw > BBThreshold_Width) and ATR_go_trade ? color.lime : color.red
	BackBBcolor := (bbw > BBThreshold_Width) and ATR_go_trade ? color.rgb(33, 250, 243, 90) : color.rgb(250, 5, 10, 90)

//Display Indicator
plot(BBbasis, "Basis", color=#FF6D00)
BBp1 = plot(BBupper, "Upper", color=BBcolor)
BBp2 = plot(BBlower, "Lower", color=BBcolor)
fill(BBp1, BBp2, title = "Background", color=BackBBcolor)

//Alerts
AlertFlatflag = false
AlertNotFlatflag = false
AlertFlat = false
AlertNotFlat = false

if BBThreshold_Type == "%"
	AlertFlatflag := (bbw_purcent > BBThreshold_Width_purcent) and ATR_go_trade ? true : false
	AlertNotFlatflag := (bbw_purcent > BBThreshold_Width_purcent) and ATR_go_trade ? false : true
	AlertFlat := (AlertFlatflag[1] == false) and AlertFlatflag
	AlertNotFlat := (AlertNotFlatflag[1] == false) and AlertNotFlatflag

if BBThreshold_Type == "Ticks"
	AlertFlatflag := (bbw > BBThreshold_Width) and ATR_go_trade ? true : false
	AlertNotFlatflag := (bbw > BBThreshold_Width) and ATR_go_trade ? false : true
	AlertFlat := (AlertFlatflag[1] == false) and AlertFlatflag
	AlertNotFlat := (AlertNotFlatflag[1] == false) and AlertNotFlatflag

alertcondition(AlertFlat , title='Market is Flat', message='Market is Flat')
alertcondition(AlertNotFlat , title='Market is not Flat', message='Market is not Flat')



