custom Bollinger bands with filters - indicator (AS)
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Adam-Szafranski

//@version=5
indicator("custom Bollinger bands with filters - indicator (AS)",'CBB-IND-(AS)',overlay = true, timeframe="", timeframe_gaps=true)
//strategy("custom Bollinger bands with filters - strategy (AS)",'CBB-STRAT-(AS)', overlay = true,initial_capital = 10000,default_qty_type=strategy.percent_of_equity,default_qty_value=100) //,use_bar_magnifier = true,process_orders_on_close = true,calc_on_every_tick = true,calc_on_order_fills = true,margin_short = 100,margin_long = 100,commission_type=strategy.commission.cash_per_contract,commission_value=0.000)
is_session(sess) =>
    not na(time('D', sess))
SS(FF_SRC, LEN) =>
    lam    = math.pi * math.sqrt(2.0) / LEN
    a1        = math.exp(-lam)
    cf2    = 2.0 * a1 * math.cos(lam)
    cf3    = -math.pow(a1, 2.0)
    cf1    = 1.0 - cf2 - cf3
    f1     = 0.0
    f1    := cf1 * (FF_SRC + nz(FF_SRC[1])) * 0.5 + cf2 * nz(f1[1]) + cf3 * nz(f1[2])
    f1
MA(FF_SRC, LEN, typeMA) =>
    switch typeMA
        'EMA'     => ta.ema     (FF_SRC, LEN)
        'HMA'     => ta.hma     (FF_SRC, LEN)
        'RMA'     => ta.rma     (FF_SRC, LEN)
        'SMA'     => ta.sma     (FF_SRC, LEN)
        'WMA'     => ta.wma     (FF_SRC, LEN)
        'SS'      => SS         (FF_SRC,LEN)
StdDev(FF_SRC, LEN, typeMA) =>
	MEAN = 0.0
	SUMSQRT = 0.0
	VAR = 0.0
    if LEN > 0
	    MEAN := MA(FF_SRC,LEN,typeMA)
	    SUMSQRT := 0
	    for counter = 0 to LEN - 1
		    SUMSQRT := SUMSQRT + math.pow(FF_SRC[counter] - MEAN, 2 )
	    VAR := SUMSQRT / LEN
	    STD = math.sqrt( VAR )
    else
	    STD = -1
//////////////////TOOLTIPS/////////////////////////////////////TOOLTIPS///////////////////////////////////TOOLTIPS//////////////////
TT_TIME = 'use custom date range?/ Enable session filter?'  ,TT_STRD = 'Starting Date - if custom'
TT_ENDD = 'Ending date - if custom'                         ,TT_OPEN = 'Allow Long/Short trades'
TT_PLOT = 'Plot BB/DC/ATR?'                                 ,TT_USEE = 'Use BB/DC/ATR?'
TT_SMTH = 'Smooth BB/ATR?'                                  ,TT_STDV = 'on/off - STDV from price/STDV from BBMA'
TT_BAND = 'Len/type of middle MA/Len of DC'                 ,TT_COLR = 'fill bollinger bands?/Plot others for debuging(overlay=false)' 
TT_BBDV = 'Len/type/multiplier for standard dev'            ,TT_BBSM = 'Len/type of smoothing for BB/Perc treshold for width filter'
TT_ATR1 = 'type/len of ATR filter'                          ,TT_ATR2 = 'Treshold and smoothing of ATR filter'
/////////////////INPUTS//////////////////////////////////INPUTS//////////////////////////////////INPUTS/////////////////
GR_MA = '----------------------START settings------------------------'
BB_USE    = input.bool    (true  ,'BB-USE', inline ='M1',group=GR_MA)
DC_USE    = input.bool    (true  ,'DC-USE', inline ='M1',group=GR_MA)
TR_USE    = input.bool    (true  ,'TR-USE', inline ='M1',group=GR_MA, tooltip =TT_USEE)
BB_PLT    = input.bool    (true  ,'BB-PLT', inline ='M2',group=GR_MA)
DC_PLT    = input.bool    (true  ,'DC-PLT', inline ='M2',group=GR_MA)
TR_PLT    = input.bool    (true  ,'TR-PLT', inline ='M2',group=GR_MA, tooltip =TT_PLOT)
SM_BBU    = input.bool    (false ,'SM-BB?', inline ='M3',group=GR_MA)
TR_SMU    = input.bool    (true  ,'SM-TR?', inline ='M3',group=GR_MA, tooltip =TT_SMTH)
BB_STD    = input.bool    (true  ,'BB-STD', inline ='M6',group=GR_MA, tooltip =TT_STDV)
CC_FIL    = input.bool    (true  ,'BG-COL', inline ='M4',group=GR_MA)
CC_REP    = input.bool    (false ,'OV-NOT', inline ='M4',group=GR_MA, tooltip =TT_COLR)     
OP_BUY    = input.bool    (true  ,'OP-BUY', inline ='M5',group=GR_MA)                       //if strategy
OP_SEL    = input.bool    (true  ,'OP-SEL', inline ='M5',group=GR_MA, tooltip =TT_OPEN)     //if strategy
GR_BB = 'Bollinger Bands and Donchian settings'
BB_LEN    = input.int     (55    ,'BB-LEN', inline ='B1',group=GR_BB)
BB_TYP    = input.string  ('SMA' ,'TYP'   , inline ='B1',group=GR_BB, options=['SS','EMA','HMA','RMA','SMA','WMA'])
DC_LEN    = input.int     (81    ,'DC-LEN', inline ='B1',group=GR_BB, tooltip =TT_BAND)
BB_DVL    = input.int     (55    ,'DV-LEN', inline ='B2',group=GR_BB)
DV_TYP    = input.string  ('SMA' ,'TYP'   , inline ='B2',group=GR_BB, options=['SS','EMA','HMA','RMA','SMA','WMA'])
BB_XDV    = input.float   (2.0   ,'DV-MUX', inline ='B2',group=GR_BB, tooltip =TT_BBDV, step = 0.1)
SM_LEN    = input.int     (55    ,'SM-LEN', inline ='B3',group=GR_BB)
SM_TYP    = input.string  ('RMA' ,'TYP'   , inline ='B3',group=GR_BB, options=['SS','EMA','HMA','RMA','SMA','WMA']) 
BB_PER    = input.float   (0.2   ,'BB-PER', inline ='B3',group=GR_BB, tooltip =TT_BBSM, step = 0.1)
GR_TR = 'Average true range filter settings'
TR_TYP    = input.string  ('SMA' ,'TR-TYP', inline ='A1',group=GR_TR, options=['SS','EMA','HMA','RMA','SMA','WMA'])
TR_LEN    = input.int     (12    ,'TR-LEN', inline ='A1',group=GR_TR, tooltip =TT_ATR1)
TR_XXX    = input.float   (0.0004,'TR-PER', inline ='A2',group=GR_TR, step = 0.00005)
TR_SMO    = input.int     (14    ,'TR-SMO', inline ='A2',group=GR_TR, tooltip =TT_ATR2)
GR_DT = 'Date and session settings'
FI_SEU    = input.bool    (false ,'DT-SES', inline ='D1',group=GR_DT)
FI_TIM    = input.bool    (false ,'DT-TIM', inline ='D1',group=GR_DT, tooltip =TT_TIME)
FI_SES    = input.session ('0300-1400'    , inline ='D4',group=GR_DT, title= 'SESSION TIME')
DT_STY    = input.int     (2000  , ''     , inline ='D2',group=GR_DT, minval   = 1900, maxval = 2100)
DT_STM    = input.int     (1     , ''     , inline ='D2',group=GR_DT, options  = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
DT_STD    = input.int     (1     , ''     , inline ='D2',group=GR_DT, tooltip =TT_STRD,options  = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31])
DT_ENY    = input.int     (2024  , ''     , inline ='D3',group=GR_DT, minval   = 1900, maxval = 2100)
DT_ENM    = input.int     (1     , ''     , inline ='D3',group=GR_DT, options  = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
DT_END    = input.int     (1     , ''     , inline ='D3',group=GR_DT, tooltip =TT_ENDD ,options  = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31])
TIMEOK    = time >= timestamp(syminfo.timezone, DT_STY, DT_STM, DT_STD, 0, 0) and time < timestamp(syminfo.timezone, DT_ENY, DT_ENM, DT_END, 0, 0)
////////////////////////CALC///////////////////////////////////////////////CALC///////////////////////////////////////////////CALC////////////////////////
SESS = is_session(FI_SES)
BBMA = MA(close,BB_LEN,BB_TYP)
BBDV = BB_STD?(StdDev(close,BB_DVL,DV_TYP)*BB_XDV):(StdDev(BBMA,BB_DVL,DV_TYP)*BB_XDV)
BBUP = BBMA+BBDV
BBDN = BBMA-BBDV
BBMA := SM_BBU?MA(BBMA,SM_LEN,SM_TYP):BBMA
BBUP := SM_BBU?MA(BBUP,SM_LEN,SM_TYP):BBUP
BBDN := SM_BBU?MA(BBDN,SM_LEN,SM_TYP):BBDN
BBDW = (BBUP-BBDN)/BBMA*100   
DCDN = ta.lowest   (BBDN, DC_LEN)
DCUP = ta.highest  (BBUP, DC_LEN)
ATRF = MA(ta.tr,TR_LEN,TR_TYP)
ATRS = TR_SMU?SS(ATRF,TR_SMO):ATRF
///////////////////////CONDITIONS/FILTERS/////////////////////////////////////////////////////CONDITIONS/FILTERS/////////////////////////////
TROK = ((ATRS>TR_XXX) and TR_USE)                  , BBOK = ((BBDW>BB_PER) and BB_USE)  
DCOK = ((DCDN==BBDN   or  DCUP==BBUP) and DC_USE)  //, REST = barstate.isconfirmed and strategy.position_size==0 //if strategy
UPOK = ((DCUP==BBUP)  and DC_USE)                  , TIME = not FI_TIM or TIMEOK 
DNOK = ((DCDN==BBDN)  and DC_USE)                  , SSOK = not FI_SEU or SESS
//////////////////////ENTRY/EXITS//////////////////////////////////////////////////ENTRY/EXITS//////////////////////////////////////////////////
//GoSHORT = false  
//GoLONGG = false
//if OP_BUY
//    if TROK and not BBOK
//        GoLONGG:=true
//    else if BBOK and UPOK
//        GoLONGG:=true
//    else 
//        GoLONGG:=false
//if OP_SEL                                             //for strategy
//    if TROK and not BBOK
//        GoSHORT:=true
//    else if BBOK and DNOK 
//        GoSHORT:=true
//    else
//        GoSHORT:=false

//Open_LONG  = (close>BBUP and GoLONGG and TIME and SSOK and REST)    ,ExLong  = DCUP[1]==BBUP[1] and DCUP!=BBUP 
//Open_SHRT  = (close<BBDN and GoSHORT and TIME and SSOK and REST)    ,ExShrt  = DCDN[1]==BBDN[1] and DCDN!=BBDN 
//if strategy.position_size==0 and Open_LONG
//    strategy.entry('L',strategy.long,comment = 'L')
//if strategy.position_size==0 and Open_SHRT
//    strategy.entry('S', strategy.short,comment = 'S')
//if strategy.position_size>0 and ExLong
//    strategy.close('L',comment = 'ExL')
//if strategy.position_size<0 and ExShrt
//    strategy.close('S',comment = 'ExS')
/////////////////////PLOTS/FILLS/BGCOLOR/ETC/////////////////////////////////////PLOTS/FILLS/BGCOLOR/ETC//////////////////
BMA = plot(BB_PLT ? BBMA    :na,'BBMA',color.rgb(36, 124, 238)  ,linewidth = 1)
BDN = plot(BB_PLT ? BBDN    :na,'BBDN',color.rgb(217, 0, 255)   ,linewidth = 2)
BUP = plot(BB_PLT ? BBUP    :na,'BBUP',color.rgb(217, 0, 255)   ,linewidth = 2)
DDN = plot(DC_PLT ? DCDN    :na,'DCDN',DCDN==BBDN?na:color.red)
DUP = plot(DC_PLT ? DCUP    :na,'DCUP',DCUP==BBUP?na:color.red)
TR1 = plot(CC_REP ? ATRF    :na,'ATRF',color.navy)                                  //Overlay = false
TR2 = plot(CC_REP ? ATRS    :na,'ATRS',color.blue)                                  //Overlay = false
BBW = plot(CC_REP ? BBDW    :na,'BBDW',color.lime)                                  //Overlay = false
BBT = plot(CC_REP ? BB_PER  :na,'BBW%',color.gray)                                  //Overlay = false
TRT = plot(CC_REP ? TR_XXX  :na,'ATR%',color.teal)                                  //Overlay = false
fill(BUP,BDN, color = CC_FIL?((DCOK and BBOK)? color.rgb(105, 233, 107, 86):TROK and TR_PLT and not BBOK?color.rgb(85, 83, 228, 52):na):na)
bgcolor(SESS and FI_SEU?color.new(#51d755, 91):na)
//fill(BUP,BDN, color = (FILL=='DC'?(UPOK and not DNOK?color.rgb(97, 223, 158, 64):DNOK and not UPOK?color.rgb(232, 85, 66, 48):DCOK?color.rgb(106, 201, 214, 62):na):na))
//fill(BUP,BDN, color = (FILL=='BB'?(BBOK?color.rgb(74, 190, 95, 60):na):na))
//fill(BUP,BDN, color = (FILL=='TR'?(TROK?color.rgb(67, 181, 231, 68):na):na))
//fill(BUP,BDN, color = (FILL=='AL'?(BBOK and DCOK ?color.rgb(88, 221, 93, 63):TROK and not BBOK?color.rgb(108, 87, 200, 53):na):na))


//////////////////SETTINGS//////////////////////////////////////SETTINGS/////////////////////////////////////SETTINGS/////////////////////

/////////5MIN-EURUSD-10%
/////MA - 55,SMA
/////DEV - 55SMA,2
/////SM - 81,RMA
/////BB WIDTH-0,2
/////DC -81
/////tr - 8, 0.00045
/////tr - SMA,14
/////
/////
