Micro Zigzag
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © HeWhoMustNotBeNamed
//                                       ░▒             
//                                  ▒▒▒   ▒▒      
//                              ▒▒▒▒▒     ▒▒      
//                      ▒▒▒▒▒▒▒░     ▒     ▒▒          
//                  ▒▒▒▒▒▒           ▒     ▒▒          
//             ▓▒▒▒       ▒        ▒▒▒▒▒▒▒▒▒▒▒  
//   ▒▒▒▒▒▒▒▒▒▒▒ ▒        ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒         
//   ▒  ▒       ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░        
//   ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░▒▒▒▒▒▒▒▒         
//   ▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒                       
//    ▒▒▒▒▒         ▒▒▒▒▒▒▒                            
//                 ▒▒▒▒▒▒▒▒▒                           
//                ▒▒▒▒▒ ▒▒▒▒▒                          
//               ░▒▒▒▒   ▒▒▒▒▓      ████████╗██████╗ ███████╗███╗   ██╗██████╗  ██████╗ ███████╗ ██████╗ ██████╗ ██████╗ ███████╗
//              ▓▒▒▒▒     ▒▒▒▒      ╚══██╔══╝██╔══██╗██╔════╝████╗  ██║██╔══██╗██╔═══██╗██╔════╝██╔════╝██╔═══██╗██╔══██╗██╔════╝
//              ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒        ██║   ██████╔╝█████╗  ██╔██╗ ██║██║  ██║██║   ██║███████╗██║     ██║   ██║██████╔╝█████╗ 
//             ▒▒▒▒▒       ▒▒▒▒▒       ██║   ██╔══██╗██╔══╝  ██║╚██╗██║██║  ██║██║   ██║╚════██║██║     ██║   ██║██╔═══╝ ██╔══╝  
//            ▒▒▒▒▒         ▒▒▒▒▒      ██║   ██║  ██║███████╗██║ ╚████║██████╔╝╚██████╔╝███████║╚██████╗╚██████╔╝██║     ███████╗
//             ▒▒             ▒                        
//@version=5
indicator("Micro Zigzag", overlay = false, max_lines_count=500)
import HeWhoMustNotBeNamed/_matrix/5 as ma

ltf = input.timeframe('1', 'Lower timeframe')

add_new_pivot(matrix<float> zigzag, array<float> pivot, simple int maxItems=20)=>
    newPivot = false
    deleteLast = false
    if(matrix.rows(zigzag) == 0)
        ma.unshift(zigzag, pivot, maxItems)
        newPivot := true
    else
        lastPivot = matrix.row(zigzag, 0)
        if array.get(lastPivot,3) == array.get(pivot,3) and array.get(pivot,0)*array.get(pivot,3) > array.get(lastPivot,0)*array.get(pivot,3)
            ma.shift(zigzag)
            deleteLast := true
        if array.get(pivot,0)*array.get(pivot,3) > array.get(lastPivot,0)*array.get(pivot,3)
            ma.unshift(zigzag, pivot, maxItems)
            newPivot := true
    [newPivot, deleteLast]


draw_line(array<float> lastPivot, array<float> currentPivot)=>
    lineColor = array.get(currentPivot,3) > 0? color.green : color.red
    ln = line.new(int(array.get(lastPivot,2)), array.get(lastPivot,0), int(array.get(currentPivot,2)), array.get(currentPivot,0), xloc.bar_time, extend.none, lineColor, line.style_solid, 1)
    ln

draw_zigzag(zigzaglines, zigzag, newPivot, deleteLast)=>
    if(deleteLast)
        line.delete(array.shift(zigzaglines))
    if(newPivot and matrix.rows(zigzag) > 1)
        pivot = matrix.row(zigzag, 0)
        lastPivot = matrix.row(zigzag, 1)
        array.unshift(zigzaglines, draw_line(lastPivot, pivot))
        if(array.size(zigzaglines) > 500)
            line.delete(array.pop(zigzaglines))


[lh, ll, lv] = request.security_lower_tf(syminfo.tickerid, ltf, [high, low, volume], true)
hIndices = array.sort_indices(lh, order.descending)
highestIndex = array.size(hIndices) >= 5? array.get(hIndices, 0) : na
lIndices = array.sort_indices(ll, order.ascending)
lowestIndex = array.size(lIndices) >= 5? array.get(lIndices, 0) : na

var zigzag = matrix.new<float>()
var zigzaglines = array.new<line>()
if not na(highestIndex) and not na(lowestIndex)
    array<float> pivothigh = array.from(high, bar_index, time, 1)
    array<float> pivotlow = array.from(low, bar_index, time, -1)
    [newPivot1, deleteLast1] = add_new_pivot(zigzag, highestIndex<lowestIndex?pivothigh:pivotlow)
    draw_zigzag(zigzaglines, zigzag, newPivot1, deleteLast1)
    [newPivot2, deleteLast2] = add_new_pivot(zigzag, highestIndex<lowestIndex?pivotlow:pivothigh)
    draw_zigzag(zigzaglines, zigzag, newPivot2, deleteLast2)
