1
votes

I'm trying to create a screener, but atm getting the error msg Cannot use a mutable variable as an argument of the security function for one of the lines of the code above.

The line with error is: c01 = security(s01, timeframe.period, condition) so I'm guessing my condition is flawed, but I've seen similar code working and can't figure it out the issue.

And btw I did see this thread, but can't understand how this apply here.

Below is (hopefully) the relevant part of the code, and you can find the entire code here in case you'd like to see it and/or re-use it.

Appreciate your help!

lookBack = input(title="Lookback", type=input.integer, defval=24, minval=2)
range = input(title="Upper & Lower Range %", type=input.integer, defval=25, minval=10)

s01 = input('BINANCE:BTCUSDT', type=input.symbol)

highestHigh = highest(high, lookBack)
lowestLow = lowest(low, lookBack)
upperRange = highestHigh - ((highestHigh - lowestLow)/range) 
lowerRange = ((highestHigh - lowestLow)/range) + lowestLow
HighAboveUpperRange = high > upperRange
LowBelowLowerRange = low < lowerRange

occurrencesAbove = sum(HighAboveUpperRange ? 1 : 0, lookBack)

triggerA = occurrencesAboveFirstHalf >= 1 ? true : false
triggerB = crossunder(low, lowerRange)
condition = triggerA and triggerB

c01 = security(s01, timeframe.period, condition)
scr_label := c01 ? scr_label + s01 + '\n' : scr_label

lab_l = label.new(
          bar_index, 0, scr_label, 
          color=color.gray, 
          textcolor=color.black, 
          style =  label.style_labeldown,
          yloc = yloc.price)

label.delete(lab_l[1])
plot(0, transp = 100)

UPDATE:

I have updated my condition to a function and my security function accordingly like so:

screenerFunc() => triggerA and triggerB and triggerC and triggerD
security(s01, res, screenerFunc())

The security function still returns the Cannot use a mutable variable as an argument of the security function though.

I have also updated the entire code here.

1
You need to format the condition as a function, then you can use it in security. - AnyDozer
@AnyDozer Thanks for the help once again. I've updated the code but it still returns the same error though (but TBH not entirely sure if I'm doing the custom function correctly). I've also updated the question above with the new piece of the code :) - 42piratas

1 Answers

2
votes

You need to move your entire trigger algorithm (with all of their dependant variables) inside of a function. something like this:

trigger(range) =>

    lRange = 100/range

    highestHigh = highest(high, lookBack)
    lowestLow = lowest(low, lookBack)

    xAxisStartsAt = bar_index[lookBack]
    xAxisFinishesAt = bar_index
    upperLimit = highestHigh
    lowerLimit = lowestLow

    upperRange = highestHigh - ((highestHigh - lowestLow)/lRange) 
    lowerRange = ((highestHigh - lowestLow)/lRange) + lowestLow

    HighAboveUpperRange = high > upperRange
    LowBelowLowerRange = low < lowerRange

    occurrencesAboveTotal   = sum(HighAboveUpperRange ? 1 : 0, lookBack)
    occurrencesAboveSecondHalf = sum(HighAboveUpperRange ? 1 : 0, lookBack/2)
    occurrencesAboveFirstHalf  = occurrencesAboveTotal - occurrencesAboveSecondHalf

    occurrencesBelowTotal   = sum(LowBelowLowerRange ? 1 : 0, lookBack)
    occurrencesBelowSecondHalf = sum(LowBelowLowerRange ? 1 : 0, lookBack/2)
    occurrencesBelowFirstHalf  = occurrencesBelowTotal - occurrencesBelowSecondHalf

    triggerA = occurrencesAboveFirstHalf >= 1 ? true : false
    triggerB = occurrencesAboveSecondHalf >= 1 ? true : false
    triggerC = occurrencesBelowFirstHalf >= 1 ? true : false
    triggerD = crossunder(low, lowerRange)

    condition = triggerA and triggerB and triggerC and triggerD

c01 = security(s01, timeframe.period,  trigger(range))

Because security function will read your entire function and it will replace contextual variables (like close, low, etc...) with proper values based on your requested timeframe and symbol. your boolean variable is just a result of an algorithm and the security function needs to know the entire algorithm so it can calculate the boolean itself.

I tested this function and it does fix the mutable error but since I moved some variables inside the function, it will produce some errors in other parts of the code which you can fix it easily yourself.