I have successfully created a script that draws a line from one pivot point to another based on some conditions.
The conditions are:
- The next (or following next) pivot points must have a high that is lower than the original pivot point high
- The next (or following next) pivot points must have its wick "touching" the original wick
- It is not allowed to draw a line if there is any higher high in the range between the original pivothigh wick and the current pivothigh wick. If several conditions are meet, a "fan of lines" from the original pivot high can be created.
I asked a question about this before here Creating a fan of lines in pinescript
I managed to do this using arrays. Result can been seen here. Purple lines are "hand drawn" and the white dashed lines comes from the script.
So far so good. BUT I have 3 problems/issues:
- When a new candle is created the script fails due to "range out of bounds". I know it comes from the var declarations of the arrays on lines 19-22. If on the 1h or above timeframe it's not a big issue but on 1m it's very annoying. But deleting the var it doesn't compile correctly.
- It's slow. Takes a couple of seconds to compute even though I'm using a while statement that prevents the "lookback" if a "top" has been detected. Then it's no longer necessary to look back anymore.
- Related to (2). I'm suspecting there is a much smarter way to do this in pinescript but I haven't figured it out yet without the use of arrays.
Here's the code.
Is it possible to do this without arrays to solve all my 3 issues above?
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © sincereStork12718
//@version=5
indicator("Pivot lines", overlay=true, max_boxes_count=500, max_lines_count=500)
//---------------------------------------
//Variable declaration
//---------------------------------------
nbrBars = bar_index
plot (nbrBars, title = "nbrBars", display = display.data_window)
plot(last_bar_index, title = "last_bar_index", display = display.data_window)
//---------------------------------------
// Pivot to downside with ARRAYS working 99.9%
//---------------------------------------
//Declare arrays
var index_array_bear = array.new<int>(last_bar_index)
var high_array = array.new<float>(last_bar_index)
var upwick_array = array.new<float>(last_bar_index)
var shadow_high = array.new<float>(last_bar_index+1)
isAttFUBear = ta.pivothigh(1,1) // For this example ta.pivothigh(1,1) will produce the same result
isFUBear = ta.pivothigh(1,1) //For this example ta.pivothigh(1,1) will produce the same result
//Get bar_index, the high and the start of the upper wick for all AttFU/FU to the downside in the series from first to last bar
var i_dn = 0
if (isAttFUBear or isFUBear) == 1
array.set(index_array_bear, i_dn, bar_index[1])
array.set(high_array, i_dn, high[1])
array.set(upwick_array, i_dn, math.max(open[1], close[1]))
i_dn += 1
var j_dn = 0
array.set(shadow_high, j_dn, high)
j_dn += 1
//Draw line from index n to all index n++ that satisfies the condition below
//1. n++ index must be lower than the n:th index, i.e. high[n++] < high[n]
//2. n++ index must have it's high above upwick of the n:th, i.e. high[n++] > upwick[n]
//3. There must be a filter that removes any high higher than high[n] and high[n++] to not draw any unneccesary lines, i.e. if a "top" is found is not longer neccecary to look backwards
cnt1 = 1
top_found = false
while i_dn >= 2 and i_dn-1-cnt1 >= 0 and top_found == false
if array.get(high_array, i_dn-1-cnt1) > array.get(high_array, i_dn-1) //Checking if previous FU is higher than the current, if NOT, check the next previous etc.
if array.get(high_array, i_dn-1) >= array.get(upwick_array, i_dn-1-cnt1) //Check if current high is retesting the wick of the previous
//testing filter high in between
high_in_range = array.new<float>(nbrBars) //Create temporary array that stores all high values between the first and last endpoints of the line
for cnt2 = array.get(index_array_bear, i_dn-1-cnt1) to array.get(index_array_bear, i_dn-1)
array.set(high_in_range, cnt2, array.get(shadow_high, cnt2))
max_high_in_range = array.max(high_in_range, 2) //Return the second highest high within the range (excluding the i-1-cnt1 which is the higest)
if array.get(high_array, i_dn-1) > max_high_in_range
line.new(array.get(index_array_bear, i_dn-1-cnt1), array.get(high_array, i_dn-1-cnt1), array.get(index_array_bear, i_dn-1), array.get(high_array, i_dn-1), color = color.white, style = line.style_dashed, width = 1)
if i_dn-1-cnt1-1 > 0 //Checking if current lookback FU is higher than previous and next. If true then stop the search
if array.get(high_array, i_dn-1-cnt1) > array.get(high_array, i_dn-1-cnt1+1) and array.get(high_array, i_dn-1-cnt1) > array.get(high_array, i_dn-1-cnt1-1)
top_found := true
cnt1 := cnt1 +1