'Get the bar_index of the first bar that has a lower low than the low of the current bar
To find divergences I'm trying to get the bar_index of the first bar that has a lower low than the low of the current bar.
I wish I could inject current bar values into the condition field of ta.valuewhen() but this is not possible.
I could use a for loop, but this is slow as hell and iterating over ALL candles, which is not necessary because I want to check the first lower pivot and not all candles are pivots.
Using ta.valuewhen(condition, source, occurrence) inside a for loop and iterate with the occurrence field is discouraged by the script itself.
Eg:
prevPivLL = na
prevPivLLI = na
// Looking back 5 pivot lows for a lower low than current low
for i = 0 to 5
prevPivotLo = ta.valuewhen(na(pivotLo), pivotLo, i)
prevPivLL := pivotLo > prevPivotLo ? pivotLo : na
prevPivLLI := bar_index - ta.valuewhen(na(pivotLo), bar_index, i)
So, what else then? Is there a better approach to this?
I have seen probably all other scripts that look for divergence, look if the current low is higher than the previous one. The thing is that the current low can be a lower one with the previous pivot, but still a higher one with a earlier pivot. I want to check against the first lower pivot, even if there are higher ones in between. After that, i stop looking (because it becomes irrelevant then).
Same goes for close btw.
This is kinda backwards from what most scripts do, but probably way more accurate.
Solution 1:[1]
You can use arrays to store the pivots and their corresponding bar indices as they occur. Then you only need to iterate through a small array of pivot values to do the evaluation.
You'll need to limit the historical search though, by the number of pivots and/or by a bar lookback limit.
//@version=5
indicator("Last pivot low index", overlay = true)
lb_limit = input.int(100, title = "bar lookback limit")
piv_limit = input.int(5, title = "number of pivots limit")
var float[] piv_l_price = array.new_float()
var int[] piv_l_index = array.new_int()
bool pivl = low > low[1] and low[1] < low[2]
if pivl
array.unshift(piv_l_price, low[1])
array.unshift(piv_l_index, bar_index[1])
if array.size(piv_l_price) > piv_limit
array.pop(piv_l_price)
array.pop(piv_l_index)
size = array.size(piv_l_price)
bool found_piv_l = false
float last_piv_l_price = na
int last_piv_l_index = na
if size > 0
for i = 0 to size - 1
temp_piv_l_price = array.get(piv_l_price, i)
temp_piv_l_index = array.get(piv_l_index, i)
if temp_piv_l_price < low and temp_piv_l_index > bar_index - lb_limit
found_piv_l := true
last_piv_l_price := temp_piv_l_price
last_piv_l_index := temp_piv_l_index
break
var line piv_l_line = line.new(x1 = na, y1 = na, x2 = na, y2 = na, color = color.teal)
if found_piv_l
line.set_xy1(piv_l_line, x = last_piv_l_index, y = last_piv_l_price)
line.set_xy2(piv_l_line, x = bar_index, y = low)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | rumpypumpydumpy |

