loxxpaaspecial
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © loxx

//@version=5

// @description loxxpaaspecial: Ehles Phase Accumulation Dominant Cycle Period with Multipler and Fitler
library("loxxpaaspecial", overlay = false)

calcComp(src, period)=>
    out = (
         (0.0962 * src +
         0.5769 * src[2] -
         0.5769 * src[4] -
         0.0962 * src[6]) * (0.075 * src[1] + 0.54))
    out
    
// @function (src, mult, filt)
// @param src float
// @param mult float
// @param filt float
// @returns result float    
export paa(float src, float mult, float filt)=>
    Smooth = 0., Detrender = 0.
    I1 = 0., Q1 = 0., Period = 0., DeltaPhase = 0., InstPeriod = 0.
    PhaseSum = 0., Phase = 0., _period = 0.
    Smooth := bar_index > 5 ? (4 * src + 3 * nz(src[1]) + 2 * nz(src[2]) + nz(src[3])) / 10 : Smooth
    ts = calcComp(Smooth, Period)
    Detrender := bar_index > 5 ? ts : Detrender

    qs = calcComp(Detrender, Period)
    Q1 := bar_index > 5 ? qs : Q1
    I1 := bar_index > 5 ? nz(Detrender[3]) : I1
    
    I1 := .15 * I1 + .85 * nz(I1[1])
    Q1 := .15 * Q1 + .85 * nz(Q1[1])
    
    Phase := nz(Phase[1])
    Phase := math.abs(I1) > 0 ? 180.0 / math.pi * math.atan(math.abs(Q1 / I1)) : Phase
    
    Phase := I1 < 0 and Q1 > 0 ? 180 - Phase : Phase
    Phase := I1 < 0 and Q1 < 0 ? 180 + Phase : Phase
    Phase := I1 > 0 and Q1 < 0 ? 360 - Phase : Phase
    
    DeltaPhase := nz(Phase[1]) - Phase
    DeltaPhase := nz(Phase[1]) < 90 and Phase > 270 ? 360 + nz(Phase[1]) - Phase : DeltaPhase
    DeltaPhase := math.max(math.min(DeltaPhase, 60), 7)

    InstPeriod := nz(InstPeriod[1])
    PhaseSum := 0
    count = 0
    
    while (PhaseSum < mult * 360 and count < 4500)
        PhaseSum += nz(DeltaPhase[count])
        count := count + 1
    
    InstPeriod := count > 0 ? count : InstPeriod

    alpha = 2.0 / (1.0 + math.max(filt, 1))
    _period := nz(_period[1]) + alpha * (InstPeriod - nz(_period[1]))
    _period := math.floor(_period) < 1 ? 1 : math.floor(_period)
    math.floor(_period)
    
    
    
//example useage
int fout = math.floor(paa(close, 1., 0.))
plot(fout)



