'My strategy.cancel does not close my trades, when criteria is met. Why?

I'm trying to hunt down a bug. My strategy wouldn't close, even if the closing criteria is met. I checked multiple point manually, using the Data Window which confirms that the exit trigger is sent and valid.

Here's my snippet:

//@version=5
strategy("HT MACD4C CHVOL", overlay=true, pyramiding=0)

currPrice = input(close, title='current price')
///////////////////
// Half trend 

var int trend = 0
var int nextTrend = 0
var float maxLowPrice = nz(low[1], low)
var float minHighPrice = nz(high[1], high)

var float up = 0.0
var float down = 0.0
float atrHigh = 0.0
float atrLow = 0.0
float arrowUp = na
float arrowDown = na

atr2 = ta.atr(100) / 2
dev = 2 * atr2

highPrice = high[math.abs(ta.highestbars(2))]
lowPrice = low[math.abs(ta.lowestbars(2))]
highma = ta.sma(high, 2)
lowma = ta.sma(low, 2)

if nextTrend == 1
    maxLowPrice := math.max(lowPrice, maxLowPrice)

    if highma < maxLowPrice and close < nz(low[1], low)
        trend := 1
        nextTrend := 0
        minHighPrice := highPrice
        minHighPrice
else
    minHighPrice := math.min(highPrice, minHighPrice)

    if lowma > minHighPrice and close > nz(high[1], high)
        trend := 0
        nextTrend := 1
        maxLowPrice := lowPrice
        maxLowPrice

if trend == 0
    if not na(trend[1]) and trend[1] != 0
        up := na(down[1]) ? down : down[1]
        arrowUp := up - atr2
        arrowUp
    else
        up := na(up[1]) ? maxLowPrice : math.max(maxLowPrice, up[1])
        up
    atrHigh := up + dev
    atrLow := up - dev
    atrLow
else
    if not na(trend[1]) and trend[1] != 1
        down := na(up[1]) ? up : up[1]
        arrowDown := down + atr2
        arrowDown
    else
        down := na(down[1]) ? minHighPrice : math.min(minHighPrice, down[1])
        down
    atrHigh := down + dev
    atrLow := down - dev
    atrLow

ht = trend == 0 ? up : down

var color buyColor = color.blue
var color sellColor = color.red

htColor = trend == 0 ? buyColor : sellColor
htPlot = plot(ht, title='HalfTrend', linewidth=2, color=htColor)

buySignal = not na(arrowUp) and trend == 0 and trend[1] == 1
sellSignal = not na(arrowDown) and trend == 1 and trend[1] == 0

htBuySignal = buySignal
htSellSignal = sellSignal

//Chaikin Voltality

Length = input.int(10, minval=1)
ROCLength = input.int(12, minval=1)
//hline(0, color=color.purple)
xPrice1 = high
xPrice2 = low
xPrice = xPrice1 - xPrice2
xROC_EMA = ta.roc(ta.ema(xPrice, Length), ROCLength)

cv_ok = xROC_EMA > 0

//MACD 4C

lastColor = color.yellow
[currMacd,_,_] = ta.macd(close[0], 12, 26, 9)
[prevMacd,_,_] = ta.macd(close[1], 12, 26, 9)

plotColor = color.black

if currMacd > 0 
    plotColor := color.green
if currMacd < 0
    plotColor := color.red

macd_long = plotColor == color.green
macd_short = plotColor == color.red

//Conditions

buy_cond3 = strategy.position_size == 0
buy_cond2 = cv_ok
buy_cond1 = macd_long
buy_cond0 = htBuySignal

sel_cond3 = strategy.position_size == 0
sel_cond2 = cv_ok
sel_cond1 = macd_short
sel_cond0 = htSellSignal

// Start conditions

startLong = buy_cond0 and buy_cond1 and buy_cond2 and buy_cond3
startShort = sel_cond0 and sel_cond1 and sel_cond2 and sel_cond3

////////////////

//Recent swing

openTrades = na(strategy.position_avg_price)

int isTradeOpen = 1
if openTrades
    isTradeOpen := 0

prevIsTradeOpen = isTradeOpen[1]

canCheckHigh = false
if prevIsTradeOpen == 1
    canCheckHigh := true

recentLow = ta.valuewhen(startLong and canCheckHigh, ta.lowest(low, 5),0)
recentHigh = ta.valuewhen(startShort and canCheckHigh,ta.highest(high, 5),0)

////////////////

//Short and long entry

entryPrices = ta.valuewhen((startShort or startLong) and canCheckHigh, ta.lowest(close, 1),0)

float shortEntry = 0.00
float longEntry = 0.00
shortEntry := ta.valuewhen(startShort, entryPrices, 0)
longEntry := ta.valuewhen(startLong, entryPrices, 0)

////////////////

exitLongCond1 = currPrice < ht
exitLongCond2 = currPrice > entryPrices
exitLong = exitLongCond1 and exitLongCond2
plot(exitLongCond1?1:0, title="isExitLongCond1?")
plot(exitLongCond2?1:0, title="isExitLongCond2?")
plot(exitLong?1:0, title="isExitLong?")

exitShortCond1 = currPrice > ht
exitShortCond2 =currPrice < entryPrices
exitShort=exitShortCond1 and exitShortCond2
plot(exitShortCond1?1:0, title="isExitShortCond1?")
plot(exitShortCond2?1:0, title="isExitShortCond2?")
plot(exitShort?1:0, title="isExitShort?")

//Entry and exit

strategy.entry("long", strategy.long, stop=recentLow, when = startLong) // enter long by market if current open great then previous high
strategy.entry("short", strategy.short, stop=recentHigh, when = startShort) // enter long by market if current open great then previous high

strategy.cancel("long", when = exitLong)
strategy.cancel("short", when = exitShort)

-I'm manually tracking every opened trade and found exit points.
-I've set up plots to monitor if exitLong or exitShort is being triggered in the data window. They both work as expected.
-Strategies would not exit, only if they hit stop loss, but not by the boolean on the "when=" parameter.

What could be the problem?

edit 1: Updated the code so it's reproducible.
edit 2: please note that I had to cut some of the code to fit the code/text ratio threshold of SO. It's still functional, and still producing the behaviour described above.



Sources

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

Source: Stack Overflow

Solution Source