Joint Conditions Strategy Suite + TradingConnector alerts bot
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Peter_O

//@version=5
strategy('Joint Conditions Strategy Suite + TradingConnector alerts bot'
	 , shorttitle='JCSS+TradingConnector bot'
	 , overlay=true
	 , margin_long=100
	 , margin_short=100
	 , close_entries_rule='ANY'
	 , default_qty_type=strategy.fixed
	 , default_qty_value=100
	 , commission_type=strategy.commission.cash_per_order
	 , commission_value=0.0003)
import Peter_O/MTFindicators/8 as MTFLIBRARY

var string tooltipValue = '4th field is used only if \'value\' is selected in the 3rd dropdown. '
						 + 'Otherwise it is ignored and value of indicator selected in 3rd dropdown is used. '
var string tooltipCustomIndicator = 'Custom indicator or series has to be selected here, so you can use it entry conditions dropdowns.'
						 + 'Read this script description to see example use.'
var string tooltipMTF = 'MTF is timeframe multiplayer. '
						 + 'For example, it you want to use RSI from 4h chart, being on 1h chart, you should enter 4 here. '
						 + 'This refers to all MTF parameters in this section.'
var string tooltipKeltner = 'Keltner Channels settings: Basis Length, ATR Length, Multiplier, MTF x. Sorry, didn\'t fit in single line :)'
var string tooltipMACD = 'MACD settings: Fast Length, Slow Length, Signal Length, MTF x. Sorry, didn\'t fit in single line :)'

//------------------------------------------------------------------------------

var string longEntryGroup = 'Long Entry - when all conditions are jointly true/skipped'
var string shortEntryGroup = 'Short Entry - when all conditions are jointly true/skipped'

var string CrossingUpOption = 'Crossing Up'
var string CrossingDownOption = 'Crossing Down'
var string GreaterThanOption = 'Greater Than'
var string LessThanOption = 'Less Than'

var string skipOption = '...SKIP...'
var string openOption = 'open'
var string highOption = 'high'
var string lowOption = 'low'
var string closeOption = 'close'
var string ohlc4Option = 'ohlc4'
var string valueOption = 'value'
var string rsiAOption = 'rsiA'
var string rsiBOption = 'rsiB'
var string rsiCOption = 'rsiC'
var string maAOption = 'maA (Moving Average A)'
var string maBOption = 'maB (Moving Average B)'
var string maCOption = 'maC (Moving Average C)'
var string adxOption = 'ADX'
var string diPlusOption = 'DI-Plus'
var string diMinusOption = 'DI-Minus'
var string stochKOption = 'Stoch%K'
var string stochDOption = 'Stoch%D'
var string bbBasisOption = 'Basis Bollinger Band'
var string bbUpperOption = 'Upper Bollinger Band'
var string bbLowerOption = 'Lower Bollinger Band'
var string kcUpperOption = 'Upper Keltner Channel Band'
var string kcLowerOption = 'Lower Keltner Channel Band'
var string macdOption = 'MACD'
var string macdSignalOption = 'MACD Signal'
var string macdHistOption = 'MACD Histogram'
var string volumeOption = 'volume'
var string volumeMAOption = 'volumeMA'
var string customIndicatorOption = 'custom indicator'

longIndicatorSelector1 = input.string(defval=maBOption,
		 options=[skipOption, openOption, highOption, lowOption, closeOption, ohlc4Option, rsiAOption, rsiBOption, rsiCOption, maAOption, maBOption, maCOption, adxOption, diPlusOption, diMinusOption, stochKOption, stochDOption, bbBasisOption, bbUpperOption, bbLowerOption, kcUpperOption, kcLowerOption, macdOption, macdSignalOption, macdHistOption, volumeOption, volumeMAOption, customIndicatorOption],
		 title='', inline='cond1long', group=longEntryGroup)
longConditionTrigger1 = input.string(defval=CrossingUpOption,
		 options=[CrossingUpOption, CrossingDownOption, GreaterThanOption, LessThanOption],
		 title='', inline='cond1long', group=longEntryGroup)
longLevelSelector1 = input.string(defval=maCOption,
		 options=[valueOption, rsiAOption, rsiBOption, rsiCOption, maAOption, maBOption, maCOption, adxOption, diPlusOption, diMinusOption, stochKOption, stochDOption, bbBasisOption, bbUpperOption, bbLowerOption, kcUpperOption, kcLowerOption, macdOption, macdSignalOption, macdHistOption, volumeOption, volumeMAOption, customIndicatorOption],
		 title='', inline='cond1long', group=longEntryGroup)
longLevelValue1 = input.float(defval=0.00, title='', inline='cond1long', group=longEntryGroup, tooltip=tooltipValue)

//------------------------------------------------------------------------------

longIndicatorSelector2 = input.string(defval=macdHistOption,
		 options=[skipOption, openOption, highOption, lowOption, closeOption, ohlc4Option, rsiAOption, rsiBOption, rsiCOption, maAOption, maBOption, maCOption, adxOption, diPlusOption, diMinusOption, stochKOption, stochDOption, bbBasisOption, bbUpperOption, bbLowerOption, kcUpperOption, kcLowerOption, macdOption, macdSignalOption, macdHistOption, volumeOption, volumeMAOption, customIndicatorOption],
		 title='and', inline='cond2long', group=longEntryGroup)
longConditionTrigger2 = input.string(defval=GreaterThanOption,
		 options=[CrossingUpOption, CrossingDownOption, GreaterThanOption, LessThanOption],
		 title='', inline='cond2long', group=longEntryGroup)
longLevelSelector2 = input.string(defval=valueOption,
		 options=[valueOption, rsiAOption, rsiBOption, rsiCOption, maAOption, maBOption, maCOption, adxOption, diPlusOption, diMinusOption, stochKOption, stochDOption, bbBasisOption, bbUpperOption, bbLowerOption, kcUpperOption, kcLowerOption, macdOption, macdSignalOption, macdHistOption, volumeOption, volumeMAOption, customIndicatorOption],
		 title='', inline='cond2long', group=longEntryGroup)
longLevelValue2 = input.float(defval=0.00, title='', inline='cond2long', group=longEntryGroup)

//------------------------------------------------------------------------------

longIndicatorSelector3 = input.string(defval=adxOption,
		 options=[skipOption, openOption, highOption, lowOption, closeOption, ohlc4Option, rsiAOption, rsiBOption, rsiCOption, maAOption, maBOption, maCOption, adxOption, diPlusOption, diMinusOption, stochKOption, stochDOption, bbBasisOption, bbUpperOption, bbLowerOption, kcUpperOption, kcLowerOption, macdOption, macdSignalOption, macdHistOption, volumeOption, volumeMAOption, customIndicatorOption],
		 title='and', inline='cond3long', group=longEntryGroup)
longConditionTrigger3 = input.string(defval=GreaterThanOption,
		 options=[CrossingUpOption, CrossingDownOption, GreaterThanOption, LessThanOption],
		 title='', inline='cond3long', group=longEntryGroup)
longLevelSelector3 = input.string(defval=valueOption,
		 options=[valueOption, rsiAOption, rsiBOption, rsiCOption, maAOption, maBOption, maCOption, adxOption, diPlusOption, diMinusOption, stochKOption, stochDOption, bbBasisOption, bbUpperOption, bbLowerOption, kcUpperOption, kcLowerOption, macdOption, macdSignalOption, macdHistOption, volumeOption, volumeMAOption, customIndicatorOption],
		 title='', inline='cond3long', group=longEntryGroup)
longLevelValue3 = input.float(defval=25.00, title='', inline='cond3long', group=longEntryGroup)

//------------------------------------------------------------------------------

shortIndicatorSelector1 = input.string(defval=maBOption,
		 options=[skipOption, openOption, highOption, lowOption, closeOption, ohlc4Option, rsiAOption, rsiBOption, rsiCOption, maAOption, maBOption, maCOption, adxOption, diPlusOption, diMinusOption, stochKOption, stochDOption, bbBasisOption, bbUpperOption, bbLowerOption, kcUpperOption, kcLowerOption, macdOption, macdSignalOption, macdHistOption, volumeOption, volumeMAOption, customIndicatorOption],
		 title='', inline='cond1short', group=shortEntryGroup)
shortConditionTrigger1 = input.string(defval=CrossingDownOption,
		 options=[CrossingUpOption, CrossingDownOption, GreaterThanOption, LessThanOption],
		 title='', inline='cond1short', group=shortEntryGroup)
shortLevelSelector1 = input.string(defval=maCOption,
		 options=[valueOption, rsiAOption, rsiBOption, rsiCOption, maAOption, maBOption, maCOption, adxOption, diPlusOption, diMinusOption, stochKOption, stochDOption, bbBasisOption, bbUpperOption, bbLowerOption, kcUpperOption, kcLowerOption, macdOption, macdSignalOption, macdHistOption, volumeOption, volumeMAOption, customIndicatorOption],
		 title='', inline='cond1short', group=shortEntryGroup)
shortLevelValue1 = input.float(defval=0.00, title='', inline='cond1short', group=shortEntryGroup)

//------------------------------------------------------------------------------

shortIndicatorSelector2 = input.string(defval=macdHistOption,
		 options=[skipOption, openOption, highOption, lowOption, closeOption, ohlc4Option, rsiAOption, rsiBOption, rsiCOption, maAOption, maBOption, maCOption, adxOption, diPlusOption, diMinusOption, stochKOption, stochDOption, bbBasisOption, bbUpperOption, bbLowerOption, kcUpperOption, kcLowerOption, macdOption, macdSignalOption, macdHistOption, volumeOption, volumeMAOption, customIndicatorOption],
		 title='and', inline='cond2short', group=shortEntryGroup)
shortConditionTrigger2 = input.string(defval=LessThanOption,
		 options=[CrossingUpOption, CrossingDownOption, GreaterThanOption, LessThanOption],
		 title='', inline='cond2short', group=shortEntryGroup)
shortLevelSelector2 = input.string(defval=valueOption,
		 options=[valueOption, rsiAOption, rsiBOption, rsiCOption, maAOption, maBOption, maCOption, adxOption, diPlusOption, diMinusOption, stochKOption, stochDOption, bbBasisOption, bbUpperOption, bbLowerOption, kcUpperOption, kcLowerOption, macdOption, macdSignalOption, macdHistOption, volumeOption, volumeMAOption, customIndicatorOption],
		 title='', inline='cond2short', group=shortEntryGroup)
shortLevelValue2 = input.float(defval=0.00, title='', inline='cond2short', group=shortEntryGroup)

//------------------------------------------------------------------------------

shortIndicatorSelector3 = input.string(defval=adxOption,
		 options=[skipOption, openOption, highOption, lowOption, closeOption, ohlc4Option, rsiAOption, rsiBOption, rsiCOption, maAOption, maBOption, maCOption, adxOption, diPlusOption, diMinusOption, stochKOption, stochDOption, bbBasisOption, bbUpperOption, bbLowerOption, kcUpperOption, kcLowerOption, macdOption, macdSignalOption, macdHistOption, volumeOption, volumeMAOption, customIndicatorOption],
		 title='and', inline='cond3short', group=shortEntryGroup)
shortConditionTrigger3 = input.string(defval=GreaterThanOption,
		 options=[CrossingUpOption, CrossingDownOption, GreaterThanOption, LessThanOption],
		 title='', inline='cond3short', group=shortEntryGroup)
shortLevelSelector3 = input.string(defval=valueOption,
		 options=[valueOption, rsiAOption, rsiBOption, rsiCOption, maAOption, maBOption, maCOption, adxOption, diPlusOption, diMinusOption, stochKOption, stochDOption, bbBasisOption, bbUpperOption, bbLowerOption, kcUpperOption, kcLowerOption, macdOption, macdSignalOption, macdHistOption, volumeOption, volumeMAOption, customIndicatorOption],
		 title='', inline='cond3short', group=shortEntryGroup)
shortLevelValue3 = input.float(defval=25.00, title='', inline='cond3short', group=shortEntryGroup)

//------------------------------------------------------------------------------

var string exitSettingsGroup = 'Exit settings'
var string bracketPercent = 'Percent'
var string bracketATR = 'ATR'
var string bracketPoints = 'Points'

tpType = input.string(title='Take profit type', defval=bracketPoints, options=[bracketPercent, bracketATR, bracketPoints], inline='takeprofit', group=exitSettingsGroup)
tpValue = input.float(title='Take profit', step=0.1, minval=0.1, defval=100, inline='takeprofit', group=exitSettingsGroup)
slType = input.string(title='Stop Loss type', defval=bracketPoints, options=[bracketPercent, bracketATR, bracketPoints], inline='stoploss', group=exitSettingsGroup)
slValue = input.float(title='Stop Loss', step=0.1, minval=0.1, defval=100, inline='stoploss', group=exitSettingsGroup)
enableTrailing = input.bool(title='Enable Trailing Stop', defval=false, inline='trailing', group=exitSettingsGroup)
trailTriggerInput = input.int(title='  Trigger', minval=1, defval=80, inline='trailing', group=exitSettingsGroup)
trailPoints = enableTrailing == false ? na : trailTriggerInput
trailOffsetInput = input.int(title='Offset', minval=1, defval=10, inline='trailing', group=exitSettingsGroup)
trailOffset = enableTrailing == false ? na : trailOffsetInput

SL =
	 slType == bracketPercent ? slValue * close / 100 :
	 slType == bracketATR ? ta.atr(14) * slValue :
	 slValue

TP =
	 tpType == bracketPercent ? tpValue * close / 100 :
	 tpType == bracketATR ? ta.atr(14) * tpValue :
	 tpValue 

//------------------------------------------------------------------------------
// Time settings for strategy

var string timeSettingsGroup = 'Time Settings'

filterTradingTimes = input.bool(true, title='Trade Only Within Sessions', inline='times', group=timeSettingsGroup)
tradingTimes = input.session('0900-1600', title='', inline='times', group=timeSettingsGroup)

isTradingSession = filterTradingTimes ? not na(time(timeframe.period, tradingTimes)) : true
bgcolor(filterTradingTimes and na(time(timeframe.period, tradingTimes)) ? color.new(color.black,85) : na, title='Not in Trading Session')

//------------------------------------------------------------------------------

var string indicatorDefinitionsGroup = 'Indicator Definitions'
var string emaOption = 'EMA'
var string smaOption = 'SMA'
var string wmaOption = 'WMA'
var string vwmaOption = 'VWMA'
var string hmaOption = 'HMA'
var string rmaOption = 'RMA'
var string demaOption = 'DEMA'

customIndicator = input.source(close, title='Custom Indicator aka Imported Source', group=indicatorDefinitionsGroup, inline='custom', tooltip=tooltipCustomIndicator)

rsiA_source = input.string(defval=closeOption, title='rsiA', options=[openOption, highOption, lowOption, closeOption, ohlc4Option], group=indicatorDefinitionsGroup, inline='rsiA')
rsiA_length = input.int(defval=5, title='', group=indicatorDefinitionsGroup, inline='rsiA')
rsiA_mtf = input.int(defval=1, title='mtf', group=indicatorDefinitionsGroup, inline='rsiA', tooltip=tooltipMTF)

rsiB_source = input.string(defval=closeOption, title='rsiB', options=[openOption, highOption, lowOption, closeOption, ohlc4Option], group=indicatorDefinitionsGroup, inline='rsiB')
rsiB_length = input.int(defval=14, title='', group=indicatorDefinitionsGroup, inline='rsiB')
rsiB_mtf = input.int(defval=1, title='mtf', group=indicatorDefinitionsGroup, inline='rsiB')

rsiC_source = input.string(defval=closeOption, title='rsiC', options=[openOption, highOption, lowOption, closeOption, ohlc4Option], group=indicatorDefinitionsGroup, inline='rsiC')
rsiC_length = input.int(defval=23, title='', group=indicatorDefinitionsGroup, inline='rsiC')
rsiC_mtf = input.int(defval=1, title='mtf', group=indicatorDefinitionsGroup, inline='rsiC')

maA_type = input.string(title='MaA', defval=emaOption, options=[emaOption, smaOption, wmaOption, vwmaOption, hmaOption, rmaOption, demaOption], inline='maA', group=indicatorDefinitionsGroup)
maA_source = input.string(defval=closeOption, options=[openOption, highOption, lowOption, closeOption, ohlc4Option], title='', inline='maA', group=indicatorDefinitionsGroup)
maA_length = input.int(defval=9, title='', inline='maA', group=indicatorDefinitionsGroup)
maA_mtf = input.int(defval=1, title='mtf', inline='maA', group=indicatorDefinitionsGroup)

maB_type = input.string(title='MaB', defval=emaOption, options=[emaOption, smaOption, wmaOption, vwmaOption, hmaOption, rmaOption, demaOption], inline='maB', group=indicatorDefinitionsGroup)
maB_source = input.string(defval=closeOption, options=[openOption, highOption, lowOption, closeOption, ohlc4Option], title='', inline='maB', group=indicatorDefinitionsGroup)
maB_length = input.int(defval=50, title='', inline='maB', group=indicatorDefinitionsGroup)
maB_mtf = input.int(defval=1, title='mtf', inline='maB', group=indicatorDefinitionsGroup)

maC_type = input.string(title='MaC', defval=emaOption, options=[emaOption, smaOption, wmaOption, vwmaOption, hmaOption, rmaOption, demaOption], inline='maC', group=indicatorDefinitionsGroup)
maC_source = input.string(defval=closeOption, options=[openOption, highOption, lowOption, closeOption, ohlc4Option], title='', inline='maC', group=indicatorDefinitionsGroup)
maC_length = input.int(defval=200, title='', inline='maC', group=indicatorDefinitionsGroup)
maC_mtf = input.int(defval=1, title='mtf', inline='maC', group=indicatorDefinitionsGroup)

diLength = input.int(defval=14, title='ADX-DMI', minval=1, maxval=50, inline='adx', group=indicatorDefinitionsGroup)
adxLength = input.int(defval=14, minval=1, title='DI Length', inline='adx', group=indicatorDefinitionsGroup)
mtf4adx = input.int(defval=1, title='mtf', inline='adx', group=indicatorDefinitionsGroup)

periodK = input.int(defval=14, title='Stch', minval=1, inline='stoch', group=indicatorDefinitionsGroup)
smoothK = input.int(defval=3, title='', minval=1, inline='stoch', group=indicatorDefinitionsGroup)
periodD = input.int(defval=3, title='', minval=1, inline='stoch', group=indicatorDefinitionsGroup)
mtf4stoch = input.int(defval=1, title='mtf', inline='stoch', group=indicatorDefinitionsGroup)

bbLength = input.int(defval=20, minval=1, title='BB', inline='bbands', group=indicatorDefinitionsGroup)
bbSource = input.string(defval=closeOption, options=[openOption, highOption, lowOption, closeOption, ohlc4Option], title='', inline='bbands', group=indicatorDefinitionsGroup)
bbMult = input.float(defval=2.0, minval=0.001, maxval=50, title='σ', inline='bbands', group=indicatorDefinitionsGroup)
mtf4bb = input.int(defval=1, title='mtf', inline='bbands', group=indicatorDefinitionsGroup)

kcLength = input.int(defval=13, minval=1, title='KC', inline='keltner', group=indicatorDefinitionsGroup, tooltip=tooltipKeltner)
kcSource = close //input.source(defval=close, title='', inline='keltner', group=indicatorDefinitionsGroup)
kcAtrLength = input.int(defval=13, minval=1, title='', inline='keltner', group=indicatorDefinitionsGroup)
kcMult = input.float(defval=1.5, minval=0.01, maxval=50, title='', inline='keltner', group=indicatorDefinitionsGroup)
mtf4keltner = input.int(defval=1, title='', inline='keltner', group=indicatorDefinitionsGroup)

macdFastLength = input.int(defval=12, title='MC', inline='macd', group=indicatorDefinitionsGroup, tooltip=tooltipMACD)
macdSource = close //input.source(defval=close, title='', inline='macd', group=indicatorDefinitionsGroup)
macdSlowLength = input.int(defval=26, title='', inline='macd', group=indicatorDefinitionsGroup)
macdSignalLength = input.int(defval=9, title='',  minval = 1, maxval = 50, inline='macd', group=indicatorDefinitionsGroup)
mtf4macd = input.int(defval=1, title='', inline='macd', group=indicatorDefinitionsGroup)

//------------------------------------------------------------------------------

convertSource(sourceInput) =>
	out =
		 sourceInput == closeOption ? close :
		 sourceInput == openOption ? open :
		 sourceInput == highOption ? high :
		 sourceInput == lowOption ? low :
		 sourceInput == ohlc4Option ? ohlc4 :
		 close
	out

maA = MTFLIBRARY.moving_average_mtf(maA_mtf, maA_type, convertSource(maA_source), maA_length)
maB = MTFLIBRARY.moving_average_mtf(maB_mtf, maB_type, convertSource(maB_source), maB_length)
maC = MTFLIBRARY.moving_average_mtf(maC_mtf, maC_type, convertSource(maC_source), maC_length)

rsiA = MTFLIBRARY.rsi_mtf(rsiA_mtf, convertSource(rsiA_source), rsiA_length)
rsiB = MTFLIBRARY.rsi_mtf(rsiB_mtf, convertSource(rsiB_source), rsiB_length)
rsiC = MTFLIBRARY.rsi_mtf(rsiC_mtf, convertSource(rsiC_source), rsiC_length)

[adx, diPlus, diMinus] = MTFLIBRARY.adx_mtf(mtf4adx, adxLength, diLength)
[stochK, stochD] = MTFLIBRARY.stoch_mtf(mtf4stoch, periodK, smoothK, periodD)
[bbBasis, bbUpper, bbLower] = MTFLIBRARY.bollingerbands_mtf(mtf4bb, bbLength, convertSource(bbSource), bbMult)
[kcUpper, kcLower] = MTFLIBRARY.keltnerchannels_mtf(mtf4keltner, kcSource, kcLength, kcAtrLength, kcMult)
[macd, macdSignal, macdHist] = MTFLIBRARY.macd_mtf(mtf4macd, macdSource, macdFastLength, macdSlowLength, macdSignalLength)
volumeMA = ta.ema(volume, 20)

getIndicator(selectionInput) =>
	out =
		 selectionInput == openOption ? open :
		 selectionInput == highOption ? high :
		 selectionInput == lowOption ? low :
		 selectionInput == closeOption ? close :
		 selectionInput == ohlc4Option ? ohlc4 : 
		 selectionInput == rsiAOption ? rsiA :
		 selectionInput == rsiBOption ? rsiB :
		 selectionInput == rsiCOption ? rsiC : 
		 selectionInput == maAOption ? maA :
		 selectionInput == maBOption ? maB :
		 selectionInput == maCOption ? maC : 
		 selectionInput == adxOption ? adx :
		 selectionInput == diPlusOption ? diPlus :
		 selectionInput == diMinusOption ? diMinus :
		 selectionInput == stochKOption ? stochK :
		 selectionInput == stochDOption ? stochD : 
		 selectionInput == bbBasisOption ? bbBasis :
		 selectionInput == bbUpperOption ? bbUpper :
		 selectionInput == bbLowerOption ? bbLower :
		 selectionInput == kcUpperOption ? kcUpper :
		 selectionInput == kcLowerOption ? kcLower : 
		 selectionInput == macdOption ? macd :
		 selectionInput == macdSignalOption ? macdSignal :
		 selectionInput == macdHistOption ? macdHist :
		 selectionInput == volumeOption ? volume :
		 selectionInput == volumeMAOption ? volumeMA :
		 selectionInput == customIndicatorOption ? customIndicator :
		 close
	out
	 
getIndicatorIfSelected(selectionInput, selectionValue) =>
	out =
		 selectionInput == rsiAOption ? rsiA :
		 selectionInput == rsiBOption ? rsiB : 
		 selectionInput == rsiCOption ? rsiC :
		 selectionInput == maAOption ? maA :
		 selectionInput == maBOption ? maB :
		 selectionInput == maCOption ? maC : 
		 selectionInput == adxOption ? adx :
		 selectionInput == diPlusOption ? diPlus :
		 selectionInput == diMinusOption ? diMinus :
		 selectionInput == stochKOption ? stochK :
		 selectionInput == stochDOption ? stochD : 
		 selectionInput == bbBasisOption ? bbBasis :
		 selectionInput == bbUpperOption ? bbUpper :
		 selectionInput == bbLowerOption ? bbLower :
		 selectionInput == kcUpperOption ? kcUpper :
		 selectionInput == kcLowerOption ? kcLower : 
		 selectionInput == macdOption ? macd :
		 selectionInput == macdSignalOption ? macdSignal :
		 selectionInput == macdHistOption ? macdHist :
		 selectionInput == volumeOption ? volume :
		 selectionInput == volumeMAOption ? volumeMA :
		 selectionInput == customIndicatorOption ? customIndicator :
		 selectionValue
	out

longIndicator1 = getIndicator(longIndicatorSelector1)
longLevel1 = getIndicatorIfSelected(longLevelSelector1, longLevelValue1)

longIndicator2 = getIndicator(longIndicatorSelector2)
longLevel2 = getIndicatorIfSelected(longLevelSelector2, longLevelValue2)

longIndicator3 = getIndicator(longIndicatorSelector3)
longLevel3 = getIndicatorIfSelected(longLevelSelector3, longLevelValue3)

shortIndicator1 = getIndicator(shortIndicatorSelector1)
shortLevel1 = getIndicatorIfSelected(shortLevelSelector1, shortLevelValue1)

shortIndicator2 = getIndicator(shortIndicatorSelector2)
shortLevel2 = getIndicatorIfSelected(shortLevelSelector2, shortLevelValue2)

shortIndicator3 = getIndicator(shortIndicatorSelector3)
shortLevel3 = getIndicatorIfSelected(shortLevelSelector3, shortLevelValue3)

GoLong1 =
	 longConditionTrigger1 == CrossingUpOption ? ta.crossover(longIndicator1, longLevel1) : 
	 longConditionTrigger1 == CrossingDownOption ? ta.crossunder(longIndicator1, longLevel1) : 
	 longConditionTrigger1 == GreaterThanOption ? longIndicator1 > longLevel1 : 
	 longConditionTrigger1 == LessThanOption ? longIndicator1 < longLevel1 : 
	 true

GoLong2 =
	 longConditionTrigger2 == CrossingUpOption ? ta.crossover(longIndicator2, longLevel2) : 
	 longConditionTrigger2 == CrossingDownOption ? ta.crossunder(longIndicator2, longLevel2) : 
	 longConditionTrigger2 == GreaterThanOption ? longIndicator2 > longLevel2 : 
	 longConditionTrigger2 == LessThanOption ? longIndicator2 < longLevel2 : 
	 true

GoLong3 =
	 longConditionTrigger3 == CrossingUpOption ? ta.crossover(longIndicator3, longLevel3) : 
	 longConditionTrigger3 == CrossingDownOption ? ta.crossunder(longIndicator3, longLevel3) : 
	 longConditionTrigger3 == GreaterThanOption ? longIndicator3 > longLevel3 : 
	 longConditionTrigger3 == LessThanOption ? longIndicator3 < longLevel3 : 
	 true

GoShort1 =
	 shortConditionTrigger1 == CrossingUpOption ? ta.crossover(shortIndicator1, shortLevel1) : 
	 shortConditionTrigger1 == CrossingDownOption ? ta.crossunder(shortIndicator1, shortLevel1) : 
	 shortConditionTrigger1 == GreaterThanOption ? shortIndicator1 > shortLevel1 : 
	 shortConditionTrigger1 == LessThanOption ? shortIndicator1 < shortLevel1 : 
	 true

GoShort2 =
	 shortConditionTrigger2 == CrossingUpOption ? ta.crossover(shortIndicator2, shortLevel2) : 
	 shortConditionTrigger2 == CrossingDownOption ? ta.crossunder(shortIndicator2, shortLevel2) : 
	 shortConditionTrigger2 == GreaterThanOption ? shortIndicator2 > shortLevel2 : 
	 shortConditionTrigger2 == LessThanOption ? shortIndicator2 < shortLevel2 : 
	 true

GoShort3 =
	 shortConditionTrigger3 == CrossingUpOption ? ta.crossover(shortIndicator3, shortLevel3) : 
	 shortConditionTrigger3 == CrossingDownOption ? ta.crossunder(shortIndicator3, shortLevel3) : 
	 shortConditionTrigger3 == GreaterThanOption ? shortIndicator3 > shortLevel3 : 
	 shortConditionTrigger3 == LessThanOption ? shortIndicator3 < shortLevel3 : 
	 true

GoLong = longIndicatorSelector1 == skipOption and longIndicatorSelector2 == skipOption and longIndicatorSelector3 == skipOption
	 ? false
	 : (
		 (longIndicatorSelector1 == skipOption ? true : GoLong1)
		 and (longIndicatorSelector2 == skipOption ? true : GoLong2)
		 and (longIndicatorSelector3 == skipOption ? true : GoLong3)
		 )

GoShort = shortIndicatorSelector1 == skipOption and shortIndicatorSelector2 == skipOption and shortIndicatorSelector3 == skipOption
	 ? false
	 : (
		 (shortIndicatorSelector1 == skipOption ? true : GoShort1)
		 and (shortIndicatorSelector2 == skipOption ? true : GoShort2)
		 and (shortIndicatorSelector3 == skipOption ? true : GoShort3)
		 )

////////////
//STRATEGY//
////////////

if GoLong and isTradingSession and strategy.position_size <= 0
	strategy.entry('long', strategy.long)
	alertMessage =
		 'long sl=' + str.tostring(SL)
		 + ' tp=' + str.tostring(TP)
		 + (enableTrailing ? ' trail=true trailtrig=' + str.tostring(trailPoints) + ' traildist=' + str.tostring(trailOffset) : '')
	alert(message=alertMessage, freq=alert.freq_once_per_bar_close)
strategy.exit('xl', from_entry='long', loss=SL, profit=TP, trail_points=trailPoints, trail_offset=trailOffset)

if GoShort and isTradingSession and strategy.position_size >= 0
	strategy.entry('short', strategy.short, when=GoShort)
	alertMessage =
		 'short sl=' + str.tostring(SL)
		 + ' tp=' + str.tostring(TP)
		 + (enableTrailing ? ' trail=true trailtrig=' + str.tostring(trailPoints) + ' traildist=' + str.tostring(trailOffset) : '')
	alert(message=alertMessage, freq=alert.freq_once_per_bar_close)
strategy.exit('xs', from_entry='short', loss=SL, profit=TP, trail_points=trailPoints, trail_offset=trailOffset)

///////////
// PLOTS //
///////////

plot(maA, title='maA', linewidth=1, color=color.new(color.lime, 0))
plot(maB, title='maB', linewidth=2, color=color.new(color.fuchsia, 0))
plot(maC, title='maC', linewidth=3, color=color.new(color.orange, 0))

////////////
//WARNINGS//
////////////

atrFullChart = ta.atr(2000) / syminfo.mintick
showWarning = (SL > 0 and SL <= atrFullChart) or (TP > 0 and TP <= atrFullChart) or (trailOffset > 0 and trailOffset <= atrFullChart)

whichBracketsAreTooTight =
	 (SL > 0 and SL <= atrFullChart) and (TP == 0 or TP > atrFullChart) and (trailOffset == 0 or na(trailOffset) or trailOffset > atrFullChart) ? 'StopLoss' :
	 (SL > 0 and SL <= atrFullChart) and (TP > 0 and TP <= atrFullChart) and (trailOffset == 0 or na(trailOffset) or trailOffset > atrFullChart) ? 'StopLoss, TakeProfit' :
	 (SL > 0 and SL <= atrFullChart) and (TP > 0 and TP <= atrFullChart) and (trailOffset > 0 and trailOffset <= atrFullChart) ? 'StopLoss, TakeProfit, Trail' :
	 (SL > 0 and SL <= atrFullChart) and (TP == 0 or TP > atrFullChart) and (trailOffset > 0 and trailOffset <= atrFullChart) ? 'StopLoss, Trail' :
	 (SL == 0 or SL > atrFullChart) and (TP > 0 and TP <= atrFullChart) and (trailOffset == 0 or na(trailOffset) or trailOffset > atrFullChart) ? 'TakeProfit' :
	 (SL == 0 or SL > atrFullChart) and (TP > 0 and TP <= atrFullChart) and (trailOffset > 0 and trailOffset <= atrFullChart) ? 'TakeProfit, Trail' :
	 (SL == 0 or SL > atrFullChart) and (TP == 0 or TP > atrFullChart) and (trailOffset > 0 and trailOffset <= atrFullChart) ? 'Trail' : 
	 ''

warningHeader = 'WARNING!'
warningHeader2 = 'Too tight ' + whichBracketsAreTooTight
warningText = 'Due to non-tick-data candle mechanisms here of TradingView, backtest results\nyou are seeing right now in the Strategy Tester are probably better than in reality.'
	 + '\n\nWhy?\n\nStrategy Tester assumes that at each candle market has first moved in your\nfavor (so while in Long position market first reached HIGH of a candle, and while\nin Short position first reached LOW), and against you after that. '
	 + 'The suggested\nworkaround, to make backtester results more real, is to increase SL/TP/Trail,\nso they are higher than ATR for this chart (this instrument on this timeframe).'
	 + '\n\nThat was in quick words, but you can learn more from this\nvideo: https://www.youtube.com/watch?v=uM5m_iUAP8g\n\nATR value (in ticks) for this chart is '
	 + str.tostring(atrFullChart) 
warningText2 = 'You can proceed with the current settings, because you still might want to set\ntight SL/TP/Trail for alerts, but be assured that backtest results ain\'t real.'

var table warningsTable = table.new(position=position.top_right, columns=1, rows=4, border_width=1)
if barstate.islastconfirmedhistory and showWarning
	table.cell(warningsTable, column=0, row=0, text=warningHeader, bgcolor=na, text_color=color.orange, text_size=size.large)
	table.cell(warningsTable, column=0, row=1, text=warningHeader2, bgcolor=na, text_color=color.orange, text_size=size.large)
	table.cell(warningsTable, column=0, row=2, text=warningText, bgcolor=na, text_color=color.teal, text_size=size.normal, text_halign=text.align_right)
	table.cell(warningsTable, column=0, row=3, text=warningText2, bgcolor=na, text_color=color.teal, text_size=size.normal, text_halign=text.align_right)
