Morning Option Pullback Indicator
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © benjaminbarch

//@version=5
indicator(title="Morning Option Pullback Indicator", shorttitle="MOPI", overlay = true)

// --- WHAT THIS INDICATOR DOES --- {
// 
// Name: MOPI (Morning Option Pullback Indicator)
//
// Use at your own risk. No guarantees come with this indicator.
// Designed for use on the 1 min chart for the SPY and QQQ tickers to assist me in Option CALL and PUT Signals
// This indicator watches for morning opening price to break above or below the pre-market channel
// Then waits for a specific type of pull back where the price touches the Medium Length EMA (EMA20 default)
// And indicates a Buy signal for a CALL or a PUT depending on certain other conditions
//
// END WHAT THIS INDICATOR DOES }


// --- INPUTS ---{

//Calculate Live or at Candle Close?
UseLiveCalculation = input.bool(defval = true, title = "Calculate on Live Candle?", group="General Settings", tooltip = "Checked = The indicator checks for the pocess during live candles at every tick. Unchecked = The Indicator looks for the process only when the Candle Closes.")
LimitOneTradePerSession = input.bool(defval = true, title = "Limit to One Trade per Session?", group="General Settings", tooltip = "Checked = Only the first signal of each session goes off per ticker, Unchecked = Subsequent signals could go off in the same day")

//Debug and Verbose Mode
DebugVerboseMode = input.bool(title="Debug Verbose Mode?", defval = true, group="General Settings", tooltip="Plots more data to help in debugging code or to just give more info")

//Close position at end of session
ClosePositionAtEndOfDay = input.bool(title="Force Close Position at End of Day?", defval = true, group="General Settings", tooltip="Closes any open positions at the end of each session if a trade has not yet hit it's Profit Target or Stop Loss")

//Take Profit and Stop Loss Settings
rewardTarget = input.float(title="Profit Target", defval = 2.0, minval=0.01, maxval = 100, step=0.1, group="Target TP/SL Points")
riskTarget = input.float(title="Stop Loss Risk", defval = 0.5, minval=0.01, maxval = 100, step=0.1, group="Target TP/SL Points")

// Ignore signals after recent entry or exit
UseIgnoreTrade = input.bool(defval = true, title = "Ignore if recent Signal -", group="History", inline="ignore", tooltip = "Helps prevent multiple signals in a row for a single entry. Ignore signaling a subsequent buy if we've recently signaled, entered, or exited a trade?")
NumCandlesToIgnore = input.int(defval=12, minval=1, maxval=1000, title="# of Candles", group="History", inline="ignore")

//EMA Hold Time
NumCandlesEMA = input.int(defval=4, minval=1, maxval=1000, title="EMA Uncrossed Candle History", group="History", tooltip="# of recent historic candles EMAs must stay apart without touching or crossing. This helps filter a clear EMA trend vs chop")

//Padding
paddingPriceToEMA = input.float(title="Price to EmaMedium Distance", defval=0.10, step=0.01, minval=0.0, maxval=1000.0, group="How Close is Close Enough?", tooltip = "Set to 0 to disable. The price distance within the price and EmaMedium line need to be to one another to consider it close enough")
//paddingPriceToPMHL = input.float(title="Price to PM H/L Distance", defval=0.15, step=0.01, minval=0.0, maxval=1000.0, group="How Close is Close Enough?", tooltip = "Set to 0 to disable. How far the price can dip back within the channel to consider it close enough to still be considrered outside the channel")

// % of PM spread
SpreadPercentUpperLimit = input.int(title="Upper % limit", defval=150, step=5, group="% price distance from H/L as related to PM spread", tooltip="If the spread of premarket was $2, then setting this to 100% allows the signal to go off up to $2 higher than the PM high. Set it to 200% and it allows it to go off up to $4 higher than the PM high line for a good signal. Keeping this in check can help deter a fake signal when there is a huge parabolic move before a first pullback")
SpreadPercentLowerLimit= input.int(title="Lower % limit", defval=-10, step=5, group="% price distance from H/L as related to PM spread", tooltip="A negative number allows the price to be under the PM high line (or witihin the channel) in case padding was used for an entry") 

//Display EMAs
DisplayEmaShort = input.bool(title="Display Short", defval=true, group="General Settings", inline="short")
EmaShortInput = input.int(title="EMA?", defval=5, step=1, group="General Settings", inline="short", tooltip="Short Time Frame EMA")
DisplayEmaMedium = input.bool(title="Display Medium", defval=true, group="General Settings", inline="medium")
EmaMediumInput = input.int(title="EMA?", defval=20, step=1, group="General Settings", inline="medium", tooltip="Medium Time Frame EMA")
DisplayEmaLong = input.bool(title="Display Long", defval=true, group="General Settings", inline="long")
EmaLongInput = input.int(title="EMA?", defval=233, step=1, group="General Settings", inline="long", tooltip="Long Time Frame EMA")

//Pre-Market Inputs
thresholdAtrPercent = input.float(title="ATR threshold %", defval=300, step=10, minval=1, maxval=10000, group="Pre-Market H/L Calculation", tooltip="Compares ATR(2) with ATR(14), Threshold must be under this number. The larger the number, the tighter to price action the PM Lines stick to. A lower number in this setting will allow quick price ation to blow over")
PreMarketSession = input.session(title="Pre-Market Hours", defval="0400-0930", group="Pre-Market H/L Calculation")

// Set the Trading Session Hours
MorningTradingSession = input.session(defval="0935-1100", title="Morning Hours", group="Trading Sessions")
//UseAfternoonSession = input.bool(defval = false, title = "Use", group="Trading Sessions", inline="Afternoon", tooltip = "Must be checked in order to use Afternoon Hours, otherwise Afternon hours will be ignored. Check the box if you want to divde your day into two separate sessions")
//AfternoonTradingSession = input.session(defval="1400-1530", title="Afternoon Hours?", group="Trading Sessions", inline="Afternoon")

// Define if we are using the TICK.US filter
UseTickFilter = input.bool(defval = false, title = "Use TICK.US Filter?", group="TICK.US Filter", tooltip = "Affects Buy signals. When checked, signals and alerts will only go off when levels exceed the threshold. Checks TICK.US to see if the average of the EMA5 and EMA20 lines on the 10 min chart are more than +/- threshold range.")
NumCandlesTICKRequirement = input.int(defval=0, minval=0, maxval=1000, title="Also require # of history Candles", group="TICK.US Filter", tooltip="Set to 0 to disable. Requires that a number of historical bars TICK.US filter also be true")
UseTickFilterBG = input.bool(defval = false, title = "Color the Background?", group="TICK.US Filter", tooltip = "Should Color be applied the background? Colors the background green if the avg >= upper threshold and red if the avg is <= lower threshold. No color if within the thresholds.")
UpperTenMinEmaTickUSthreshold = input.int(title="TICK.US Upper avg threshold", defval=100, minval=1, maxval=1000, step=50, group="TICK.US Filter", tooltip="The average of the EMA 5 and EMA 20 of the TICK.US chart on the 10 min timeframe. This is the threshold which will trigger a green background. 100 by default")
LowerTenMinEmaTickUSthreshold = input.int(title="TICK.US Lower avg threshold", defval=-100, minval=-1000, maxval=-1, step=50, group="TICK.US Filter", tooltip="The average of the EMA 5 and EMA 20 of the TICK.US chart on the 10 min timeframe. This is the threshold which will trigger a red background. -100 by default")

okToTradeMonday = input.bool(defval = true, title = "Monday", group="Trading Days", tooltip = "Which days of the week do you want to get signals? For instance I leave Friday turned off because it's the worst performing day of the week for this indicator")
okToTradeTuesday = input.bool(defval = true, title = "Tuesday", group="Trading Days", tooltip = "Which days of the week do you want to get signals? For instance I leave Friday turned off because it's the worst performing day of the week for this indicator")
okToTradeWednesday = input.bool(defval = true, title = "Wednesday", group="Trading Days", tooltip = "Which days of the week do you want to get signals? For instance I leave Friday turned off because it's the worst performing day of the week for this indicator")
okToTradeThursday = input.bool(defval = true, title = "Thursday", group="Trading Days", tooltip = "Which days of the week do you want to get signals? For instance I leave Friday turned off because it's the worst performing day of the week for this indicator")
okToTradeFriday = input.bool(defval = true, title = "Friday", group="Trading Days", tooltip = "Which days of the week do you want to get signals? For instance I leave Friday turned off because it's the worst performing day of the week for this indicator")

SignalBoxColor = input.color(defval = color.new(color.blue, 0), title = "Signal Box Color", group = "Box Color")
ProfitBoxColor = input.color(defval = color.new(color.green, 0), title = "Profit Box Color", group = "Box Color")
LossBoxColor = input.color(defval = color.new(color.red, 0), title = "Loss Box Color", group = "Box Color")

// --- END INPUTS --- }


// --- VARIABLES --- {
var float PMcalculatedHigh = na // The ending results of the calculated PreMarketSession
var float PMcalculatedLow = na
var currentlyInCallTrade = false
var currentlyInPutTrade = false
var TradedToday = false
var BuyCallSignal = false
var BuyPutSignal = false
var float TP = na
var float SL = na
var float EntryPrice = na


atr2 = ta.atr(2)
atr14 = ta.atr(14)
CurrentAtrPercent = 0.0
EmaShort = ta.ema(close, EmaShortInput)
EmaMedium = ta.ema(close, EmaMediumInput)
EmaLong = ta.ema(close,EmaLongInput)
SellProfitSignal = false
SellLossSignal = false
recentSignal = false // resets back to false to start every calulation and we will check to see if it's true with each new tick
EmaShortStayedAboveEmaMediumRecently = false
EmaShortStayedBelowEmaMediumRecently = false
IsTickBeyondThreshold = false
IsTickHistoryBeyondThreshold = false
BarCloseAndLowOnOppositeSidesOfEmaMedium = false //used when Live Calcluation is off.
BarCloseAndHighOnOppositeSidesOfEmaMedium = false
lastBarOfRegularHours = false
okToTradeThisDay = false

// --- END VARIABLES --- }


// --- CUSTOM FUNCTIONS --- {

//establish a new function to check if we are in a session. This will simplify the code.
isInSession(_sess) => not na(time(timeframe.period, _sess))

// --- END CUSTOM FUNCTIONS }





// --- MAIN BODY CALCULATIONS --- {

//Check if we are ok to trade this day of week
if dayofweek == 2 and okToTradeMonday
    okToTradeThisDay := true
else if dayofweek == 3 and okToTradeTuesday
    okToTradeThisDay := true
else if dayofweek == 4 and okToTradeWednesday
    okToTradeThisDay := true
else if dayofweek == 5 and okToTradeThursday
    okToTradeThisDay := true
else if dayofweek == 6 and okToTradeFriday
    okToTradeThisDay := true




//Check if this is the last bar of the day
if hour == 15 and minute == 59
    lastBarOfRegularHours := true

// Highlight the last bar in the session with a fuchsia background for debugging
//bgcolor(lastBarOfRegularHours ? color.new(color.fuchsia, 80) : na)

//Reset the TradedToday boolean flag at the beginning of each session 
if isInSession(MorningTradingSession) and not isInSession(MorningTradingSession)[1] // First tick of Morning session
    TradedToday := false
//else if isInSession(AfternoonTradingSession) and not isInSession(AfternoonTradingSession)[1] // First tick of Afternoon session
//    TradedToday := false


// --- GET PRE-MARKET H/L --- {
CurrentAtrPercent := (atr2 / atr14) * 100
if isInSession(PreMarketSession) and (not isInSession(PreMarketSession)[1]) // If this is the first bar of pre-market
    PMcalculatedHigh := na //reset variables
    PMcalculatedLow := na
if isInSession(PreMarketSession)
    if (na(PMcalculatedHigh) and CurrentAtrPercent <= thresholdAtrPercent) or (CurrentAtrPercent <= thresholdAtrPercent and (close > PMcalculatedHigh or open > PMcalculatedHigh))//If we don't have a Calculated PM High yet or our current open/close is higher, update the calcuated highest
        PMcalculatedHigh := close > open ? close : open //store the higher of either the open or the close
    if (na(PMcalculatedLow) and CurrentAtrPercent <= thresholdAtrPercent) or (CurrentAtrPercent <= thresholdAtrPercent and (close < PMcalculatedLow or open < PMcalculatedLow))
        PMcalculatedLow := close < open ? close : open

// --- END GET PRE-MARKET H/L}

// --- CHECKING THE PROCESS ---{

// TICK.US Filter data - Check the EMA5 and EMA20 on the TICK.US 10 min chart.
extendedTicker = ticker.modify("TICK.US", session = session.extended) //set session to include extended hours. default session for request security function only grabs data from regular hours.
ema5TICK = request.security(symbol=extendedTicker, timeframe="10", expression=ta.ema(close, 5)) // We want repainting to happen and get the most recent calculation, dont code it out
ema20TICK = request.security(symbol=extendedTicker, timeframe="10", expression=ta.ema(close, 20))
tenMinEmaTickUS = (ema5TICK + ema20TICK) / 2 // Get the average of the EMA5/20 lines and set our "ten min TICK EMA variable"

if (tenMinEmaTickUS > UpperTenMinEmaTickUSthreshold or tenMinEmaTickUS < LowerTenMinEmaTickUSthreshold) // Are we over or under the threshold (outside of the channel)
    IsTickBeyondThreshold := true
else
    IsTickBeyondThreshold := false


// Is Price Crossing Under EMA 20 line and wasn't on the previous candle?
priceCrossingUnderEmaMedium = (low-paddingPriceToEMA <= EmaMedium and low[1] > EmaMedium)
priceCrossingAboveEmaMedium = (high+paddingPriceToEMA >= EmaMedium and high[1] < EmaMedium)


//Is this completed bar close on one side of EMA while it's low/high end is on the other side of EmaMedium? This tells us if the bar is in a freefall against our potential trade direction, or if we've touched and reversed. We only want in if we've touched and reversed
BarCloseAndLowOnOppositeSidesOfEmaMedium := barstate.isconfirmed and (close - paddingPriceToEMA) > EmaMedium and (low - paddingPriceToEMA) <= EmaMedium // for a Call trade
BarCloseAndHighOnOppositeSidesOfEmaMedium := barstate.isconfirmed and (close + paddingPriceToEMA) < EmaMedium and (high + paddingPriceToEMA) >= EmaMedium // for a Put trade


// Have we had a recent signal or currently in a trade?
for i = 1 to NumCandlesToIgnore
    if BuyCallSignal[i] or BuyPutSignal[i] or currentlyInCallTrade[i] or currentlyInPutTrade[i]
        recentSignal := true // this gets erased, recreated, and set to false by default at the start of this code every time


// Has TICK.US History stayed Beyond Threshold?
for i = 0 to NumCandlesTICKRequirement
    if IsTickBeyondThreshold[i]
        IsTickHistoryBeyondThreshold := true // this gets erased, recreated, and set to false by default at the start of this code every time
    else
        IsTickHistoryBeyondThreshold := false
        break //once we find a false history, leave variable set as false


// Has EmaShort stayed above EmaMedium over recent x number of candles?
for i = 1 to NumCandlesEMA
    if EmaShort[i] > EmaMedium[i]
        EmaShortStayedAboveEmaMediumRecently := true
    else //as soon as a false is detected, break out of this loop and leave variable set to false
        EmaShortStayedAboveEmaMediumRecently := false
        break
// Has EmaShort stayed below EmaMedium over recent x number of candles?
for i = 1 to NumCandlesEMA
    if EmaShort[i] < EmaMedium[i]
        EmaShortStayedBelowEmaMediumRecently := true
    else //as soon as a false is detected, break out of this loop and leave variable set to false
        EmaShortStayedBelowEmaMediumRecently := false
        break


// Calculate % of the PM Spread that the EmaMedium is from PM High
PercentOfPMSpreadAboveHigh = (EmaMedium - PMcalculatedHigh) / (PMcalculatedHigh - PMcalculatedLow) * 100
WithinTolerablePMSpreadRangeAboveHigh = PercentOfPMSpreadAboveHigh >= SpreadPercentLowerLimit and PercentOfPMSpreadAboveHigh <= SpreadPercentUpperLimit
// Calculate % of the PM Spread that the close is from PM Low
PercentOfPMSpreadBelowLow = (PMcalculatedLow - EmaMedium) / (PMcalculatedHigh - PMcalculatedLow) * 100
WithinTolerablePMSpreadRangeBelowLow = PercentOfPMSpreadBelowLow >= SpreadPercentLowerLimit and PercentOfPMSpreadBelowLow <= SpreadPercentUpperLimit


// Calculate if Buy signals are true
//BuyCallSignal := (isInSession(MorningTradingSession) == true) and priceCrossingUnderEmaMedium and EmaMedium+paddingPriceToPMHL > PMcalculatedHigh and (close + paddingPriceToPMHL) > PMcalculatedHigh and EmaShortStayedAboveEmaMediumRecently and WithinTolerablePMSpreadRangeAboveHigh and (UseTickFilter ? (IsTickBeyondThreshold and IsTickHistoryBeyondThreshold) : true) and (UseIgnoreTrade ? (recentSignal or currentlyInCallTrade == true ? false : true) : true) and (UseLiveCalculation ? true : BarCloseAndLowOnOppositeSidesOfEmaMedium) and (LimitOneTradePerSession ? not TradedToday : true) and okToTradeThisDay
BuyCallSignal := (isInSession(MorningTradingSession) == true) and priceCrossingUnderEmaMedium and EmaShortStayedAboveEmaMediumRecently and WithinTolerablePMSpreadRangeAboveHigh and (UseTickFilter ? (IsTickBeyondThreshold and IsTickHistoryBeyondThreshold) : true) and (UseIgnoreTrade ? (recentSignal or currentlyInCallTrade == true ? false : true) : true) and (UseLiveCalculation ? true : BarCloseAndLowOnOppositeSidesOfEmaMedium) and (LimitOneTradePerSession ? not TradedToday : true) and okToTradeThisDay
//BuyPutSignal := (isInSession(MorningTradingSession) == true) and priceCrossingAboveEmaMedium and EmaMedium-paddingPriceToPMHL < PMcalculatedLow and (close - paddingPriceToPMHL) < PMcalculatedLow and EmaShortStayedBelowEmaMediumRecently and WithinTolerablePMSpreadRangeBelowLow and (UseTickFilter ? (IsTickBeyondThreshold and IsTickHistoryBeyondThreshold) : true) and (UseIgnoreTrade ? (recentSignal  or currentlyInPutTrade == true ? false : true) : true) and (UseLiveCalculation ? true : BarCloseAndHighOnOppositeSidesOfEmaMedium) and (LimitOneTradePerSession ? not TradedToday : true) and okToTradeThisDay
BuyPutSignal := (isInSession(MorningTradingSession) == true) and priceCrossingAboveEmaMedium and EmaShortStayedBelowEmaMediumRecently and WithinTolerablePMSpreadRangeBelowLow and (UseTickFilter ? (IsTickBeyondThreshold and IsTickHistoryBeyondThreshold) : true) and (UseIgnoreTrade ? (recentSignal  or currentlyInPutTrade == true ? false : true) : true) and (UseLiveCalculation ? true : BarCloseAndHighOnOppositeSidesOfEmaMedium) and (LimitOneTradePerSession ? not TradedToday : true) and okToTradeThisDay


//Calculate TP/SL points upon entering a trade
if (BuyCallSignal and currentlyInCallTrade == false)
    EntryPrice := (UseLiveCalculation ? EmaMedium + paddingPriceToEMA : close)
    currentlyInCallTrade := true
    TradedToday := true
    TP := EntryPrice + rewardTarget
    SL := EntryPrice - riskTarget
if (BuyPutSignal and currentlyInPutTrade == false)
    EntryPrice := (UseLiveCalculation ? EmaMedium - paddingPriceToEMA : close)
    currentlyInPutTrade := true
    TradedToday := true
    TP := EntryPrice - rewardTarget
    SL := EntryPrice + riskTarget




// --- END CHECKING THE PROCESS}
// --- END MAIN BODY CALCULATIONS ---}


// --- PLOT DATA --- {

//plot the Buy Call and Buy Put Signals for Strategy Testers signal input. It uses 1 for buy and -1 for sell
plot((BuyCallSignal or BuyPutSignal) ? (BuyCallSignal ? 1 : -1) : na, title="Buy/Sell Signal for Strategy Tester", display = display.none )

//plot the calculated Pre-Market High/Low Lines
plot(PMcalculatedHigh-PMcalculatedLow, title="Pre-market Spread", display = display.status_line, color = color.gray)
plot(PMcalculatedHigh, title="Calculated PM High Line", color=color.new(color.green, 50), style=plot.style_linebr, display = display.pane)
plot(PMcalculatedLow, title="Calculated PM Low Line", color=color.new(color.red, 50), style=plot.style_linebr, display = display.pane)

//set the bg color based on TICK.US settings if option selected
bgcolor(color=UseTickFilterBG ? (tenMinEmaTickUS >= UpperTenMinEmaTickUSthreshold ? color.new(color=color.green, transp=90) : tenMinEmaTickUS <= LowerTenMinEmaTickUSthreshold ? color.new(color=color.red, transp = 90) : na) : na, title="BG TICK.US Color", editable=false)

//Plot the EMA's if turned on
plot(DisplayEmaShort ? EmaShort : na, title="EMA Short Line", color=color.aqua, style=plot.style_line, linewidth = 2)
plot(DisplayEmaMedium ? EmaMedium : na, title="EMA Medium Line", color=color.yellow, style=plot.style_line, linewidth = 2)
plot(DisplayEmaLong ? EmaLong : na, title="EMA Long Line", color=color.red, style=plot.style_circles, linewidth = 1)

//Plot the Buy Signals
plotshape(BuyCallSignal, title="Buy Call Signal", style=shape.triangleup, color=color.green, location=location.belowbar, size=size.normal, display = display.pane)
plotshape(BuyPutSignal, title="Buy Put Signal", style=shape.triangledown, color=color.red, location=location.abovebar, size=size.normal, display = display.pane)

//Plot the TP and SL targets
plot((currentlyInCallTrade or currentlyInPutTrade) ? TP : na, title="Take Profit Line", color = color.new(color.green, 0), style=plot.style_linebr)
plot((currentlyInCallTrade or currentlyInPutTrade) ? SL : na, title="Stop Loss Line", color = color.new(color.red, 0), style=plot.style_linebr)


//If we are in a trade, should exit the trade?
if currentlyInCallTrade == true
    //has price hit TP/SL targets or is it the end of the day? If hit or end of day, reset TP/SL back to na and flag the sell signal
    if (high >= TP) or (high >= EntryPrice and hour == 15 and minute == 59)
        SellProfitSignal := true
    if (low <= SL) or (low <= EntryPrice and hour == 15 and minute == 59)
        SellLossSignal := true
        
if currentlyInPutTrade == true
    if (low <= TP) or (low <= EntryPrice and hour == 15 and minute == 59)
        SellProfitSignal := true
    if (high >= SL) or (high >= EntryPrice and hour == 15 and minute == 59)
        SellLossSignal := true



//Verbose mode
if DebugVerboseMode
    if BuyCallSignal
        truncPerc = math.round(PercentOfPMSpreadAboveHigh, 1)
        truncEntryPrice = math.round(EntryPrice, 2)
        textString = "Distance= " + str.tostring(truncPerc) + "%\nEnter CALL at " + str.tostring(truncEntryPrice) + ".\n TP=" + str.tostring(truncEntryPrice + rewardTarget) + "\n SL=" + str.tostring(truncEntryPrice - riskTarget)
        mylabel = label.new(x=bar_index[0], y=high + atr14 * 3, text=textString, style=label.style_label_down, color = SignalBoxColor)
    if BuyPutSignal
        truncPerc = math.round(PercentOfPMSpreadBelowLow, 1)
        truncEntryPrice = math.round(EntryPrice, 2)
        textString = "Distance= " + str.tostring(truncPerc) + "%\nEnter PUT at " + str.tostring(truncEntryPrice) + ".\n TP=" + str.tostring(truncEntryPrice - rewardTarget) + "\n SL=" + str.tostring(truncEntryPrice + riskTarget)
        mylabel = label.new(x=bar_index, y=low - atr14 * 3, text=textString, style=label.style_label_up, color = SignalBoxColor)
    if SellProfitSignal or SellLossSignal
        if SellProfitSignal
            ExitPrice = (lastBarOfRegularHours ? close : math.round(TP, 2))
            ProfitPoints = math.abs(math.round(ExitPrice - EntryPrice, 2))
            textString = "Exit Profit at "+ str.tostring(ExitPrice) + "\n " + str.tostring(ProfitPoints) + " Points"
            mylabel = label.new(x=bar_index, y=high + atr14 * 3, text=textString, style=label.style_label_down, color = ProfitBoxColor)
        if SellLossSignal
            ExitPrice = (lastBarOfRegularHours ? close : math.round(SL, 2))
            LossPoints = math.round(ExitPrice - EntryPrice, 2)
            textString = "Exit Loss at " + str.tostring(ExitPrice) + "\n " + str.tostring(LossPoints) + " Points"
            mylabel = label.new(x=bar_index, y=low - atr14 * 3, text=textString, style=label.style_label_up, color = LossBoxColor)
// }


// --- ALERT CONDITIONS --- {
alertcondition(BuyCallSignal, title="Buy CALL Signal", message="CALL signal for {{ticker}} at {{close}}")
alertcondition(BuyPutSignal, title="Buy PUT Signal", message="PUT signal for {{ticker}} at {{close}}")
alertcondition((SellProfitSignal or SellLossSignal), title="SELL Position Signal", message="SELL signal for {{ticker}} at {{close}}")


// --- END ALERT CONDITIONS --- }


// --- RESET VARIABLES AT END --- {
// Lastly Reset our variables if we exited a trade
if (currentlyInCallTrade or currentlyInPutTrade) and (SellLossSignal or SellProfitSignal)
    TP := na
    SL := na
    currentlyInCallTrade := false
    currentlyInPutTrade := false
    EntryPrice := na
// }