'Price crossing levels in both directions, in realtime bar, not activating subsequent alerts

My code is configured to initiate an alert whenever the current price crosses a predetermined buy/sell level. This part works. However, in certain time frames (e.g. over 5 minutes) it happens that there is a spike where the current price crosses the buy/sell level more than once, in the same realtime bar. The 1 minute time setting is too fast to see this kind of behaviour.

I have an alert to tell me if the realtime candle's open/high and close/low have crossed both the buy and sell levels. But my current code only reacts when the crossover is in one direction. Obviously, when it is in short, it should not signal another short, and vice versa. But if in a short it should be able to goto a long, and then back to a short, etc, in the same realtime candle.

My problem is: I am unable to see where or what in my code is preventing or by-passing the above description from happening.

// This source code is PRIVATE
// © WaxBill2k 2205091

//@version=5
indicator("MyIndicator2", overlay = true, max_labels_count = 200)

// Initialize boolean for plotshape series
var bool actBuy = false
var bool actSell = false

// Initialize first Buy and Sell levels
var float buy_level = 0
var float sell_level = 0

// Initialize previous Buy and Sell levels
var float buy_level_pre = na
var float sell_level_pre = na

// Initialize 2Bars
bool blueBar = false
bool redBar = false
bool twoBlueBars = false
bool twoRedBars = false

// Initialize alerts
varip bool isLong = false
varip bool isShort = false
bool buySig = false
bool sellSig = false
var int spiky = 0
var string p = "na"

// Initialize bar conditions
bool cdHigh = high > buy_level or close > buy_level
bool cdLow = low < sell_level or close < sell_level

// Time counters
timeLeft = barstate.isrealtime ? (time_close - timenow) / 1000 : na
secLeft = barstate.isrealtime ? str.format("{0,time,mm:ss}", time_close - timenow) : na

// Find 2Bars
redBar := barstate.isconfirmed and open < close
blueBar := barstate.isconfirmed and open > close

// Set 2Bars
twoBlueBars := blueBar and blueBar[1]
twoRedBars := redBar and redBar[1]

// Calc bars
if twoBlueBars or twoRedBars
    buy_level := math.max(high[1], high)
    sell_level := math.min(low[1], low)
else
    buy_level :=buy_level[1]
    sell_level := sell_level[1]

// goto BUY (sell_level)
if cdHigh and not actBuy
    actBuy := true
    actSell := false
    p := "A"
// goto SELL (buy_level)
else if cdLow and not actSell
    actBuy := false
    actSell := true
    p := "B"
// goto SPIKE alert
else if cdHigh and cdLow
    if actBuy
        actBuy := false
        actSell := true
        p := "C"
    else if actSell
        actBuy := true
        actSell := false
        p := "D"

// Spiky alert
if cdHigh and cdLow
    spiky := spiky + 1
    if actBuy and cdHigh
        alert('SPIKE UP [' + str.tostring(secLeft) + '] ' + str.tostring(spiky), alert.freq_once_per_bar)
    else if actSell and cdLow
        alert('SPIKE DOWN [' + str.tostring(secLeft) + '] ' + str.tostring(spiky), alert.freq_once_per_bar)

// Save previous levels
if (actSell and actBuy[1]) or (actBuy and actSell[1])
    buy_level_pre := buy_level[1]
    sell_level_pre := sell_level[1]

var ln_max = line.new(na, na, na, na, extend = extend.right, color = color.blue)
var ln_min = line.new(na, na, na, na, extend = extend.right, color = color.orange)

if bar_index > 1
    line.set_xy1(ln_max, bar_index - 1, buy_level)
    line.set_xy2(ln_max, bar_index, buy_level)
    line.set_xy1(ln_min, bar_index - 1, sell_level)
    line.set_xy2(ln_min, bar_index, sell_level)

// buy only if buy_sig triggered and not already long
buySig := not isLong and actBuy

// sell only if sell_sig triggered and not already short
sellSig := not isShort and actSell

// alert trigger
if buySig
    if isLong == true
        isLong := false
    else
        isLong := true
    isShort := false
    alert('BUY price: ' + str.tostring(p) + ' [' + str.tostring(secLeft) + '] ' + str.tostring(buy_level), alert.freq_all)
else if sellSig
    isLong := false
    if isShort == true
        isShort := false
    else
        isShort := true
    alert('SELL price: ' + str.tostring(p) + ' [' + str.tostring(secLeft) + '] ' + str.tostring(sell_level), alert.freq_all)


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source