I would like to compute the slope/derivative of each zigzag line, and show them above/below the zigzag line. How to do this?
Example of zigzag:
//@version=4
study("ZigZagSlope", overlay = true, max_bars_back = 500, max_lines_count = 300)
prd = input(defval = 3, title="ZigZag Period", minval = 2, maxval = 50)
showzigzag = input(defval = true, title = "Show Zig Zag")
upcol = input(defval = color.black, title = "Zigzag Up Color")
dncol = input(defval = color.black, title = "Zigzag Down Color")
float ph = highestbars(high, prd) == 0 ? high : na
float pl = lowestbars(low, prd) == 0 ? low : na
var dir = 0
dir := iff(ph and na(pl), 1, iff(pl and na(ph), -1, dir))
var max_array_size = 10
var zigzag = array.new_float(0)
add_to_zigzag(value, bindex)=>
array.unshift(zigzag, bindex)
array.unshift(zigzag, value)
if array.size(zigzag) > max_array_size
array.pop(zigzag)
array.pop(zigzag)
update_zigzag(value, bindex)=>
if array.size(zigzag) == 0
add_to_zigzag(value, bindex)
else
if (dir == 1 and value > array.get(zigzag, 0)) or (dir == -1 and value < array.get(zigzag, 0))
array.set(zigzag, 0, value)
array.set(zigzag, 1, bindex)
0.
Round_it(value)=> round(value / syminfo.mintick) * syminfo.mintick
dirchanged = change(dir)
if ph or pl
if dirchanged
add_to_zigzag(dir == 1 ? ph : pl, bar_index)
else
update_zigzag(dir == 1 ? ph : pl, bar_index)
if showzigzag and array.size(zigzag) >= 4
var line zzline = na
float val = array.get(zigzag, 0)
int point = round(array.get(zigzag, 1))
if change(val) or change(point)
float val1 = array.get(zigzag, 2)
int point1 = round(array.get(zigzag, 3))
if change(val1) == 0 and change(point1) == 0
line.delete(zzline)
zzline := line.new(x1 = point, y1 = val, x2 = point1, y2 = val1, color = dir == 1 ? upcol : dncol, width = 2)
Example of computation of derivatives:
https://www.tradingview.com/script/1Ea3KEUq-MaxWarren-s-Pine-Acceleration-2nd-Derivative/
Slope is rise over run, in this case it is by (val - val1) / (point - point1)
. Which is the price difference over the the bar_index
difference.
You can add it to your script as follows, I've included the variable values in the label so you can confirm them manually.
Comparing the current slope to the 2nd previous one of the same direction, we need to check first if it exists in the array by checking the array size again. Then we can retrieve the price and bar_index values from the array and do the same rise/run calculation and compare the existing zigzag's slope to the 2nd previous one.
//@version=4
study("ZigZagSlope", overlay = true, max_bars_back = 500, max_lines_count = 300)
prd = input(defval = 3, title="ZigZag Period", minval = 2, maxval = 50)
showzigzag = input(defval = true, title = "Show Zig Zag")
upcol = input(defval = color.black, title = "Zigzag Up Color")
dncol = input(defval = color.black, title = "Zigzag Down Color")
float ph = highestbars(high, prd) == 0 ? high : na
float pl = lowestbars(low, prd) == 0 ? low : na
var dir = 0
dir := iff(ph and na(pl), 1, iff(pl and na(ph), -1, dir))
var max_array_size = 10
var zigzag = array.new_float(0)
add_to_zigzag(value, bindex)=>
array.unshift(zigzag, bindex)
array.unshift(zigzag, value)
if array.size(zigzag) > max_array_size
array.pop(zigzag)
array.pop(zigzag)
update_zigzag(value, bindex)=>
if array.size(zigzag) == 0
add_to_zigzag(value, bindex)
else
if (dir == 1 and value > array.get(zigzag, 0)) or (dir == -1 and value < array.get(zigzag, 0))
array.set(zigzag, 0, value)
array.set(zigzag, 1, bindex)
0.
Round_it(value)=> round(value / syminfo.mintick) * syminfo.mintick
dirchanged = change(dir)
if ph or pl
if dirchanged
add_to_zigzag(dir == 1 ? ph : pl, bar_index)
else
update_zigzag(dir == 1 ? ph : pl, bar_index)
if showzigzag and array.size(zigzag) >= 4
var line zzline = na
var label slope_label = na
float val = array.get(zigzag, 0)
int point = round(array.get(zigzag, 1))
if change(val) or change(point)
float val1 = array.get(zigzag, 2)
int point1 = round(array.get(zigzag, 3))
if change(val1) == 0 and change(point1) == 0
line.delete(zzline)
label.delete(slope_label)
zzline := line.new(x1 = point, y1 = val, x2 = point1, y2 = val1, color = dir == 1 ? upcol : dncol, width = 2)
slope = (val - val1) / (point - point1)
debug_vals_text = "\nval : " + tostring(val) + "\nval1 : " + tostring(val1) + "\npoint : " + tostring(point) + "\npoint1 : " + tostring(point1)
slope_text = "slope : " + tostring(slope)
string slope2_text = na
float slope2 = na
if array.size(zigzag) >= 8
val2 = array.get(zigzag, 4)
point2 = array.get(zigzag, 5)
val3 = array.get(zigzag, 6)
point3 = array.get(zigzag, 7)
slope2 := (val2 - val3) / (point2 - point3)
slope2_text := "\nval2 : " + tostring(val2) + "\nval3 : " + tostring(val3) + "\npoint2 : " + tostring(point2) + "\npoint3 : " + tostring(point3) + "\nprev slope : " + tostring(slope2)
slope_diff_text = "\n\nslope diff : " + tostring(slope - slope2)
slope_label := label.new(x = point, y = val, text = slope_text + "\n\n" + debug_vals_text + slope2_text + slope_diff_text, style = val > val1 ? label.style_label_down : label.style_label_up, size = size.small)