Neo-Fractals for AmiBroker Community

Neo-Fractals for AmiBroker Community

First and foremost, I would like to acknowledge two experts "Mr. @empottasch and Mr. @JohnHT" whose work has significantly contributed to this project. The codes I utilized from this forum were originally created by them, and they deserve full credit for their efforts. Special thanks to Mr. @empottasch and Mr. @JohnHT. Despite having a logical understanding of the solution, my current level of AFL (AmiBroker Formula Language) knowledge would not have allowed me to practically implement it without their codes.

Further, I warmly welcome any expert who wishes to contribute to enhancing the performance or adding features to this code. Your contributions would be greatly appreciated.

Introductory Comment:

Here, I introduce a completely new type of fractals, which I have named 'Neo-Fractals'. These Neo-Fractals offer a fresh approach compared to traditional fractals and may be of interest to traders.
It's common knowledge among technical analysts that a zigzag based on fractals is the best choice if you want to maximize the number of peaks and troughs. This is beneficial for pattern detection, as more peaks and troughs increase the number of detectable patterns. However, too many peaks and troughs can clutter the chart and generate patterns too small to be useful. To address this, I have used an existing fractal code taken from one of Mr. @empottasch's online code that employs HHV (Highest High Value) and LLV (Lowest Low Value) functions, and modified it to suit my needs. After using that code, it still generates a great number of peaks and troughs, but not the extremely large number of peaks and troughs.

A Note on My English:

Being a monk and Ayurvedic doctor, untill a few past months, my focus has been mostly on Sanskrit texts and thereby -- inspite of being able to clearly understand the English without any single effort-- I lack in expressing myself in English. I heavily rely on online translators, so my expressions may not be clear. I appreciate your patience and effort.

Key Instructions:

The sequence of the three sections of this AFL code must not be altered. The three sections are named: "Clean Base Peak-Trough," "Find Missed Peak-Trough," and "Again Clean Peak-Trough." Additionally, the internal codes within the "Find Missed Peak-Trough" section must remain in their original order. Altering them might superficially seem to map price activity nicely, but it won't hold up upon closer inspection. I confirm this on the basis of a thorough examination of numerous charts across different time frames.

Solving Common Problems of ZigZags:

  1. Alternating peaks-troughs and maintaining the accuracy of mapping:
    One persistent problem with fractals is the inability to ensure that peaks and troughs alternate perfectly WHILE SIMULTANEOUSLY keeping the accuracy of the price-activity's mapping intact. This zigzag addresses this issue by utilizing Neo-Fractals, and then applying Mr. @empottasch's code to remove excess peak-and-trough signals.

  2. Missed pivots:
    Second common issue with zigzags is that they occasionally miss marking a high or low that should be identified as a peak or trough. The solution involves first identifying such missed pivots and marking them correctly, followed by cleaning up excess peaks and troughs. I was fortunate to successfully code a method for this, and Mr. @JohnHT also shared a solution at the very same time. I opted to use Mr. @JohnHT's solution due to its superior performance and efficiency. Many thanks to Mr. @JohnHT for sharing his work.

One might wonder why zigzags miss these pivots. The explanation is complex and inherent to the nature of zigzags. No matter how peaks and troughs are defined, occasional skipping is inevitable. This issue can only be addressed after defining the peaks and troughs. For a visual example, you can refer to my posts here: Forum Link.

  1. Peak and Trough on the very same-bar:
    A third problem is the issue of Peak and Trough being on the very same-bar. One mathematical solution to avoid this is to create a zigzag that skips all inside bars and then handle the outside bars. However, this approach has a significant drawback: if a large bar occurs, the zigzag will not map the price activity until the high or low of the large bar is crossed, ignoring the entire price activity within that range. The price activity within the range of large-bar is crucial for predicting price direction and estimating the minimum-distance price can travel in the direction of the breakout, especially when a trade is already has been placed and one needs to make a decision exit or remain in the market.

And if one ignores the above solution and simply let the zigzag to ignore such bars then it is going to require many number of bars ( numbers of bars required depend on the relative-size of large bar ) for the new peaks and troughs to freshly start the accurate mapping of the price-activity. Before this fresh stablization, one can not rely on those peaks and troughs. Therefore, it is very important that long bars which have both the peak & trough at their high and low are not skipped by the zigzag.

To address this, the Gfx functions are used in this zigzag to handle the bars where a peak and trough occur on the same bar. These functions connect the left and right pivots to such a bar and also show a vertical line covering the bar's length. The rest of the zigzag lines are generated without Gfx functions, making this a combination of regular and Gfx lines.

  1. Repainting fractals
    Fractal peaks and troughs typically repaint, but this issue is largely resolved here. The exception is the very last leg, which remains uncertain and can repaint. However, ignoring this last leg, the recent zigzag leg before it does not repaint in the opposite direction, ensuring overall mapping accuracy. Ideally, I would like to code this last leg in a different color to indicate its uncertainty, but my current level of AFL (AmiBroker Formula Language) knowledge limiting me to practically implement it. I hope that some expert would come forward to help in this matter.

Final Thought:

Zigzags should not be used directly for trading. They are tools for mapping price activity and can lead to biases about future price direction. While zigzags are important to me, I always analyze a naked chart first, then view it with a zigzag plot. I suggest the same approach to everyone.

End Note:

If anyone is interested in understanding the rationale behind the Neo-Fractals, feel free to ask. The explanation may require several snapshots.

// AFL-Name: Neo-Fractals
// Author: @LotusHear ( Sunil Hooda aka Shivoham ) from https://forum.amibroker.com/
// Deticated: To AmiBroker Forum Community and to Mr.'Tomasz Janeczko' ( The owner & chief software architect of AmiBroker )
// Credits: All the credit goes to Mr. @empottasch ( Edward Pottasch ) and Mr. @JohnHT ( John Stone ) from https://forum.amibroker.com/
// Codes used in this AFL are the work of: Mr. @empottasch ( Edward Pottasch ) and Mr. @JohnHT ( John Stone )
// AFL Code Date: 12-July-2024

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


_SECTION_BEGIN( "Date-Time etc." );


RequestTimedRefresh( 1 );

TTDC = ParamColor( "Title-Text's Default-Color", colorWhite );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

MT_Start = BeginValue( BarIndex() );
MT_End = EndValue( BarIndex() );
MT_Periods = MT_End - MT_Start;
MT_ValueStart = BeginValue( C );
MT_ValueEnd = EndValue( C );
MT_Difference = MT_ValueEnd - MT_ValueStart;
MT_Percentage = NumToStr( ( ( MT_Difference / MT_ValueStart ) * 100 ), 1.2 );
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

function GetSecondNum()
{
    Time = Now( 4 );
    Seconds = int( Time % 100 );
    Minutes = int( Time / 100 % 100 );
    Hours = int( Time / 10000 % 100 );
    SecondNum = int( Hours * 60 * 60 + Minutes * 60 + Seconds );
    return SecondNum;
}

TimeFrame = Interval();
SecNumber = GetSecondNum();
NewPeriod = SecNumber % TimeFrame == 0;
SecsLeft = SecNumber - int( SecNumber / TimeFrame ) * TimeFrame;
SecsToGo = TimeFrame - SecsLeft;

if( NewPeriod )
{
    Say( "New period" );
}

LastBar_Price = EndValue( Close );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

SetChartOptions( 0, chartShowArrows | chartShowDates );
//TimeFrame = in1Minute * Param( "Time Frame (min)", 5, 1, 1440 * 10, 1 ); // 1440 minutes is 1 day
TimeFrame = in1Minute * Interval() / 60 * 1;  // Param( "Chart Time Frame Factor", 1, 1, 10, 1 ); // factor 1 uses timeframe of chart
_N( Title = EncodeColor( TTDC ) + /* GfxSetTextColor(Text_Background_Color) + */ StrFormat( "Symbol-Name  =  {{NAME}}  ||  Visible-Chart  Date-&-Time  =  {{DATE}}  ||  Open %g  |  High %g  |  Low %g  |  Close %g  |  ROC (%.1f%%)  || " +
            "                                                                                  Last-Price  =  " + LastBar_Price + "\n TimeFrame: " + TimeFrame / 60 + " Minutes | " + TimeFrame / 3600 + " Hours | " + TimeFrame / ( 3600 * 24 ) + " Days  || " +
            " Total-Bars  =  " + MT_Periods + "  ||  Total %%Change  =  " + MT_Percentage + "  ||  Current-Time  =  " + Now( 2 ) + "  ||  CountDown to Bar-Close  =  " + SecsToGo +
            "{{VALUES}} ", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ) );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

// SetBarsRequired( -2, -2 );
Bi = BarIndex();
BC = BarCount - 1;

xCum = Cum( 1 );

FvB = FirstVisibleValue( Bi );
LvB = LastVisibleValue( Bi );

StartBar = BeginValue( Bi );
EndBar = EndValue( Bi );

SelectedBar = SelectedValue( Bi );
LastBar = LastValue( Bi );

SetBarsRequired( ( LvB - FvB ) * 4 );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

GraphXSpace = Param( "GraphXSpace", 10, 0, 100, 1 );
GraphLabelDecimals = Param( "Graph-Label's Decimals", 3, 0, 100, 1 );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Font_Name = ParamList( "Font", "Tahoma|Helvetica|Arial Black|Verdana|Courier New|Times New Roman|Open Sans|Compact|Segoe UI|DejaVu Sans", 1 );
Text_Size = Param( "Text-Size", 8, 5, 20, 1 );
Text_Color = ParamColor( "Gfx Background-Color", colorWhite );

Plot( C, "Close", ParamColor( "Color", colorDefault ), styleNoTitle | ParamStyle( "Style" ) | GetPriceStyle() );

_SECTION_END();

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


_SECTION_BEGIN( "Price-Mode" );


PriceArrayMode_Switch = ParamToggle( "Use Close or High and Low price", "Use Close|Use High and Low", 1 );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

if( PriceArrayMode_Switch == 1 )
{
    PaH = High;
    PaL = Low;
}
else
    if( PriceArrayMode_Switch == 0 )
    {
        PaH = C;
        PaL = C;
    }


_SECTION_END();

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


_SECTION_BEGIN( "ZigZag Prameters" );


nZigZag_DisplaySwitch = ParamToggle( "Display Base-ZigZag ", "No|Yes", 1 );
nZZ_PeakTrough_Shapes_DisplaySwitch = ParamToggle( "Display ZZ's PeakTrough-Shapes", "No|Yes", 1 );
nPivot_Labels_DisplaySwitch = ParamToggle( "Display nPivot-Labels", "No|Yes", 1 );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
pZigZag_DisplaySwitch = ParamToggle( "Display Prime-ZigZag ", "No|Yes", 0 );
pZZ_PeakTrough_Shapes_DisplaySwitch = ParamToggle( "Display pZZ's PeakTrough-Shapes", "No|Yes", 0 );
pPivot_Labels_DisplaySwitch = ParamToggle( "Display pPivot-Labels", "No|Yes", 0 );


_SECTION_END();

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


_SECTION_BEGIN( "Define nNeo-Fractals" );


nRightside_NeoFractal_Strength = Param( "Base-Zigzag's Neo-Fractal Strength", 1, 1, 50, 1 );
nLeftside_NeoFractal_Strength = nRightside_NeoFractal_Strength; // Param( "nLeftside Neo-Fractal-Strength", 1, 0, 50, 1 );
nNeoFractal_Strength_Factor = Param( "Base-Zigzag Neo-Fractal Strength-Factor", 1, 1, 20, 1 );

nRsNFS = nRightside_NeoFractal_Strength;
nLsNFs = nLeftside_NeoFractal_Strength;
nNFSF = nNeoFractal_Strength_Factor;

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Neo_HighsideInBar = PaH == Ref( PaH, -1 ) AND PaL >= Ref( PaL, -1 );
Neo_LowersideInBar = PaL == Ref( PaL, -1 ) AND  PaH <= Ref( PaH, -1 );
Neo_InBar = Neo_HighsideInBar OR Neo_LowersideInBar;

nscPaH = Nz( SparseCompress( !Neo_InBar, PaH ) );
nscPaL = Nz( SparseCompress( !Neo_InBar, PaL ) );
nscIdx = Nz( SparseCompress( !Neo_InBar, Bi ) );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

//nscUp_NeoFractal = nscPaH > Ref( nscPaH, -1 ) AND nscPaH >= Ref( nscPaH, 1 );
//nscDown_NeoFractal =  nscPaL < Ref( nscPaL, -1 ) AND nscPaL <= Ref( nscPaL, 1 );

iLsNFS = iRsNFS = iNFSF = iPaH = iPaL = iUp_NeoFractal = iDown_NeoFractal = 0;           

// This function is taken from one of online codes from  Mr. @empottasch ( Edward Pottasch )
// Modified it as per my need 
function Calculate_Main_Pivots( iLsNFS, iRsNFS, iNFSF, iPaH, iPaL )
{
iUp_NeoFractal = iPaH > Ref( HHV( iPaH, iLsNFS * iNFSF ), -1 ) AND iPaH >= Ref( HHV( iPaH, iRsNFS * iNFSF ), iRsNFS * iNFSF );
iDown_NeoFractal = iPaL < Ref( LLV( iPaL, iLsNFS * iNFSF ), -1 ) AND iPaL <= Ref( LLV( iPaL, iRsNFS * iNFSF ), iRsNFS * iNFSF );            
}

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Calculate_Main_Pivots( nLsNFs, nRsNFS, nNFSF, nscPaH, nscPaL );

nscUp_NeoFractal = iUp_NeoFractal;
nscDown_NeoFractal = iDown_NeoFractal;

nUp_NeoFractal = Nz( SparseExpand( !Neo_InBar, nscUp_NeoFractal ) );
nDown_NeoFractal = Nz( SparseExpand( !Neo_InBar, nscDown_NeoFractal ) );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

nPeak = nUp_NeoFractal;
nTrough = nDown_NeoFractal;


_SECTION_END();

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

// This loop is taken from one of online codes from  Mr. @empottasch ( Edward Pottasch )

_SECTION_BEGIN( "Clean nPeak-Trough" );


// 'clean' the pivots function
// meaning make the pivots alternate like Peak-Trough-Peak-Trough-Peak-Trough-etc..

xnPeak = xnTrough = 0;

function Alternate_PeakTrough( xnPeak, xnTrough )
{
    global xnPeak_g;
    global xnTrough_g;

    // alternate pivots
    xnPeak_g = xnPeak;
    xnTrough_g = xnTrough;
    xnPeakHigh = 0;
    xnPeakHighIndex = 0;
    xnTroughLow = 1e10;
    xnTroughLowIndex = 0;

    for( i = 0; i < BarCount - 1; i++ )
    {
        // consecutive lower trough found
        if( xnTrough[i] AND L[i] <= xnTroughLow )
        {
            // disable the previous higher trough
            xnTrough_g[xnTroughLowIndex] = 0;
            // update trough variables
            xnTroughLow = L[i];
            xnTroughLowIndex = i;
            // reset peak variables
            xnPeakHigh = 0;
            xnPeakHighIndex = 0;
        }
        else

            // consecutive higher trough found
            if( xnTrough[i] AND L[i] > xnTroughLow )
            {
                // disable this trough
                xnTrough_g[i] = 0;
                // reset peak variables
                xnPeakHigh = 0;
                xnPeakHighIndex = 0;
            }

            else

                // consecutive higher peak found
                if( xnPeak[i] AND H[i] >= xnPeakHigh )
                {
                    // disable the previous lower peak
                    xnPeak_g[xnPeakHighIndex] = 0;
                    // update new peak variables
                    xnPeakHigh = H[i];
                    xnPeakHighIndex = i;
                    // reset trough variables
                    xnTroughLow = 1e10;
                    xnTroughLowIndex = 0;
                }
                else

                    // consecutive lower peak found
                    if( xnPeak[i] AND H[i] < xnPeakHigh )
                    {
                        // disable this peak
                        xnPeak_g[i] = 0;
                        // reset trough variables
                        xnTroughLow = 1e10;
                        xnTroughLowIndex = 0;
                    }

    }
}

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

// run clean pivots
Alternate_PeakTrough( nPeak, nTrough );
nPeak = xnPeak_g;
nTrough = xnTrough_g;

_SECTION_END();

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


// This code is contributed by Mr. @JohnHT ( John Stone )

_SECTION_BEGIN( "Find Missed nPeak-nTrough" );


// Find Missed Peak

nTrough_Bars = BarsSince( nTrough );
nHH_Bars = HHVBars( High, nTrough_Bars );      // Bars back to higher high since nTrough (if > 0, it is bars back to missed Peak)
nHH_Bars_Peak = IIf( nPeak, nHH_Bars, 0 );  // Restrict to current Peak bar
nHH_Bars_Peak_Reverse = Reverse( nHH_Bars_Peak );    // Can't change past so reverse time
nHH_Bars_Peak_Bars_Reverse = ValueWhen( nHH_Bars_Peak_Reverse, nHH_Bars_Peak_Reverse );   // Hold 'bars back to new Peak' forward in reversed time
nPeak_Bar_New_Reverse = Ref( nHH_Bars_Peak_Reverse, -nHH_Bars_Peak_Bars_Reverse ) == nHH_Bars_Peak_Bars_Reverse;  // Find new Peak bar in reversed time
nPeak_Bar_New = Reverse( nPeak_Bar_New_Reverse );    // Restore time direction

nPeak = ( nPeak OR nPeak_Bar_New ) AND NOT nHH_Bars_Peak;   // Add new Peak signal and remove old

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

// Find Missed Trough

nPeak_Bars = BarsSince( nPeak );
nLL_Bars = LLVBars( Low, nPeak_Bars );      // Bars back to lower low since nPeak (if > 0, it is bars back to missed Trough)
nLL_Bars_Trough = IIf( nTrough, nLL_Bars, 0 );  // Restrict to current Trough bar
nLL_Bars_Trough_Reverse = Reverse( nLL_Bars_Trough );    // Can't change past so reverse time
nLL_Bars_Trough_Bars_Reverse = ValueWhen( nLL_Bars_Trough_Reverse, nLL_Bars_Trough_Reverse );   // Hold 'bars back to new Trough' forward in reversed time
nTrough_Bar_New_Reverse = Ref( nLL_Bars_Trough_Reverse, -nLL_Bars_Trough_Bars_Reverse ) == nLL_Bars_Trough_Bars_Reverse;  // Find new Trough bar in reversed time
nTrough_Bar_New = Reverse( nTrough_Bar_New_Reverse );    // Restore time direction

nTrough = ( nTrough OR nTrough_Bar_New ) AND NOT nLL_Bars_Trough;   // Add new Trough signal and remove old



_SECTION_END();

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


_SECTION_BEGIN( "Again Clean nPeak-nTrough" );


ynPeak = ynTrough = 0;
// run clean pivots
Alternate_PeakTrough( nPeak, nTrough );
nPeak = xnPeak_g;
nTrough = xnTrough_g;


_SECTION_END();

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


// This loop is taken from one of online codes from  Mr. @empottasch ( Edward Pottasch )

_SECTION_BEGIN( "nPivots-Camparision" );


for( i = 0; i < 3; i++ )
{
    VarSet( "nPeak_x" + i, ValueWhen( nPeak, Bi, i ) );
    VarSet( "nTrough_x" + i, ValueWhen( nTrough, Bi, i ) );
    VarSet( "nPeakHigh_" + i, ValueWhen( nPeak, PaH, i ) );
    VarSet( "nTroughLow_" + i, ValueWhen( nTrough, PaL, i ) );
}

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

nLowerLow = nTrough AND nTroughLow_1 < nTroughLow_2;           // LL = LowerLow
nHigherLow = nTrough AND nTroughLow_1 > nTroughLow_2;          // HL = HigherLow
nHigherHigh = nPeak AND nPeakHigh_1 > nPeakHigh_2;             // HH = HigherHigh
nLowerHigh = nPeak AND nPeakHigh_1 < nPeakHigh_2;              // LH = LowerHigh
nDoubleTop = nPeak AND nPeakHigh_1 == nPeakHigh_2;             // DT = DoubleTop
nDoubleBottom = nTrough AND nTroughLow_1 == nTroughLow_2;      // DB = DoubleBottom

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

nPeakBar_01 =  ValueWhen( nPeak, Bi, 1 );
nPeakBar_02 =  ValueWhen( nPeak, Bi, 2 );
nPeakBar_03 = ValueWhen( nPeak, Bi, 3 );
nTroughBar_01 = ValueWhen( nTrough, Bi, 1 );
nTroughBar_02 = ValueWhen( nTrough, Bi, 2 );
nTroughBar_03 = ValueWhen( nTrough, Bi, 3 );

nPeakBarHigh_01 =  ValueWhen( nPeak, PaH, 1 );
nPeakBarHigh_02 =  ValueWhen( nPeak, PaH, 2 );
nPeakBarHigh_03 =  ValueWhen( nPeak, PaH, 3 );
nTroughBarLow_01 = ValueWhen( nTrough, PaL, 1 );
nTroughBarLow_02 = ValueWhen( nTrough, PaL, 2 );
nTroughBarLow_03 = ValueWhen( nTrough, PaL, 3 );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

nLast_Pivot_Peak = nPeakBar_01 > nTroughBar_01;
nLast_Pivot_Trough = nTroughBar_01 > nPeakBar_01;

nRecent_Pivot_Peak = nPeakBar_02 > nTroughBar_02 AND nTroughBar_01 > nPeakBar_02;
nRecent_Pivot_Trough = nTroughBar_02 > nPeakBar_02 AND nPeakBar_01 > nTroughBar_02;

nPrevious_Pivot_Peak = nPeakBar_02 < nTroughBar_02 AND nTroughBar_02 < nPeakBar_01 AND nPeakBar_01 < nTroughBar_01;
nPrevious_Pivot_Trough = nTroughBar_02 < nPeakBar_02 AND nPeakBar_02 < nTroughBar_01 AND nTroughBar_01 < nPeakBar_01;

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

nPeakTrough_SameBar_01 = nPeakBar_01 == nTroughBar_01;
nPeakTrough_SameBar_02 = nPeakBar_02 == nTroughBar_02;
nPeakTrough_SameBar_03 = nPeakBar_02 == nTroughBar_01 AND nPeakBar_03 > nTroughBar_02;
nPeakTrough_SameBar_04 = nTroughBar_02 == nPeakBar_01 AND nTroughBar_03 > nPeakBar_02;


_SECTION_END();

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


// This code is taken from one of online codes from  Mr. @empottasch ( Edward Pottasch )

_SECTION_BEGIN( "nZigZag Pivot's Lables" );


//nPivot_Labels_DisplaySwitch = ParamToggle( "Display nPivot-Labels", "No|Yes", 1 );
nPivot_Labels_Zorder = Param( "nPivot-Label's Zorder", 5, -5, 5, 1 );
nPivot_Label_Background_Color = ParamColor( "nLabel's Background-Color", colorBlack );
nPivot_Upper_Label_Color = ParamColor( "nUpper-Label Color", colorYellow );
nPivot_Lower_Label_Color = ParamColor( "nLower-Lable Color", colorCustom11 );
nPivot_Upper_Label_vPosition = Param( "nUpper-Label's Vertical-Position", 30, 0, 100, 1 );
nPivot_Lower_Label_vPosition = Param( "nLower-Label's Vertical-Position", -30, 0, -100, 1 );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


if( nPivot_Labels_DisplaySwitch == 1 )
{
    GfxSetZOrder( nPivot_Labels_Zorder );

    for( i = 0; i < BarCount - 1; i++ )
    {
        if( nLowerLow[i] )
        {
            nString = "LL";
            PlotTextSetFont( nString, Font_Name, Text_Size, i, Low[i], nPivot_Lower_Label_Color, nPivot_Label_Background_Color, nPivot_Lower_Label_vPosition );
        }

        if( nHigherLow [i] )
        {
            nString = "HL";
            PlotTextSetFont( nString, Font_Name, Text_Size, i, Low[i], nPivot_Lower_Label_Color, nPivot_Label_Background_Color, nPivot_Lower_Label_vPosition );
        }

        if( nHigherHigh[i] )
        {
            nString = "HH";
            PlotTextSetFont( nString, Font_Name, Text_Size, i, High[i], nPivot_Upper_Label_Color, nPivot_Label_Background_Color, nPivot_Upper_Label_vPosition );
        }

        if( nLowerHigh[i] )
        {
            nString = "LH";
            PlotTextSetFont( nString, Font_Name, Text_Size, i, High[i], nPivot_Upper_Label_Color, nPivot_Label_Background_Color, nPivot_Upper_Label_vPosition );
        }

        if( nDoubleTop[i] )
        {
            nString = "DT";
            PlotTextSetFont( nString, Font_Name, Text_Size, i, High[i], nPivot_Upper_Label_Color, nPivot_Label_Background_Color, nPivot_Upper_Label_vPosition );
        }

        if( nDoubleBottom[i] )
        {
            nString = "DB";
            PlotTextSetFont( nString, Font_Name, Text_Size, i, Low[i], nPivot_Lower_Label_Color, nPivot_Label_Background_Color, nPivot_Lower_Label_vPosition );
        }
    }
}

_SECTION_END();

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


// Except the Gfx code the rest of the code taken from one of online codes from  Mr. @empottasch ( Edward Pottasch )

_SECTION_BEGIN( "Base-ZigZag" );


// nZigZag_DisplaySwitch = ParamToggle( "Display nZigZag ", "No|Yes", 1 );
// nZZ_SwingStart_Shapes_DisplaySwitch = ParamToggle( "Display ZZ's SwingStart-Shapes", "No|Yes", 0 );
// nZZ_PeakTrough_Shapes_DisplaySwitch = ParamToggle( "Display ZZ's PeakTrough-Shapes  ", "No|Yes", 0 );
// nZZ_Trail_Line_DisplaySwitch = ParamToggle( "Display ZZ's Trail-Line ", "No|Yes", 0 );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

nZZ_Line_Zorder = Param( "nZZ Line-Zorder", 4, -5, 5, 1 );
nZZ_Line_Width = Param( "nZZ Line-Width", 2, 1, 5, 1 );
nZZ_Line_Style = ParamStyle( "nZZ Line-Style", styleLine | styleNoRescale | styleNoLabel );
nGFX_Line_Style = Param( "nGFX Line-Style", 0, 0, 5, 1 ); // Solid=0, Dash=1, Dot=2, Null=5 (Invisible-Pen).

nZZ_UpLine_Color = ParamColor( "nZZ's UpLine-Color", colorTurquoise );
nZZ_DownLine_Color =  ParamColor( "nZZ DownLine-Color", colorTurquoise );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

nZZ_Peak_Shape_Color = ParamColor( "nZZ Peak Shape-Color", colorCustom12 );
nZZ_Trough_Shape_Color = ParamColor( "nZZ Trough Shape-Color", colorYellow );

nZZ_Peak_Shape_Type = Param( "nZZ Peak Shape-Type", 13, 0, 50, 1 );
nZZ_Trough_Shape_Type = Param( "nZZ Trough Shape-Type", 13, 0, 50, 1 );

nZZ_Peak_Shape_vPosition = Param( "nZZ Peak-Shape's Vertical-Position", 10, 0, 100, 1 );
nZZ_Trough_Shape_vPosition = Param( "nZZ Trough-Shape's Vertical-Position", -10, 0, -100, 1 );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

iaPeak = iaTrough = 0;
iaZigZag = Null;

function Calculate_ZigZag( iaPeak, iaTrough )
{
// create ZigZag array Line
    ZZ_Up = Flip( iaTrough, iaPeak );
    ZZ_UpLow = ValueWhen( iaTrough, PaL, 1 );
    ZZ_UpHigh = ValueWhen( iaPeak, PaH, 0 );
    ZZ_UpLowIdx = ValueWhen( iaTrough, Bi, 1 );
    ZZ_UpHighIdx = ValueWhen( iaPeak, Bi, 0 );
    ZZ_SlopeUp = IIf( ZZ_Up, ( ZZ_UpHigh - ZZ_UpLow ) / ( ZZ_UpHighIdx - ZZ_UpLowIdx ) , Null );
    ZZ_UpLine = IIf( ZZ_Up, ZZ_UpLow + ZZ_SlopeUp * BarsSince( iaTrough ), Null );

    ZZ_Down = Flip( iaPeak, iaTrough );
    ZZ_DownLow = ValueWhen( iaTrough, PaL, 0 );
    ZZ_DownHigh = ValueWhen( iaPeak, PaH, 1 );
    ZZ_DownLowIdx = ValueWhen( iaTrough, Bi, 0 );
    ZZ_DownHighIdx = ValueWhen( iaPeak, Bi, 1 );
    ZZ_SlopeDown = IIf( ZZ_Down, ( ZZ_DownLow - ZZ_DownHigh ) / ( ZZ_DownLowIdx - ZZ_DownHighIdx ) , Null );
    ZZ_DownLine = IIf( ZZ_Down, ZZ_DownHigh + ZZ_SlopeDown * BarsSince( iaPeak ), Null );

    ZigZag = IIf( ZZ_Up, ZZ_UpLine, IIf( ZZ_Down, ZZ_DownLine, Null ) );
    ZigZag = IIf( Bi > Max( LastValue( ValueWhen( iaTrough, Bi ) ), LastValue( ValueWhen( iaPeak, Bi ) ) ), Null, ZigZag );

    return ZigZag;
}

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

function Calculate_LastSegment( iaPeak, iaTrough, iaZigZag )
{
    Line1 = Null;
    Last_PeakIdx = LastValue( ValueWhen( iaPeak, Bi ) );
    Last_TroughIdx = LastValue( ValueWhen( iaTrough, Bi ) );
    Last_PeakValue = LastValue( ValueWhen( iaPeak, PaH ) );
    Last_TroughValue = LastValue( ValueWhen( iaTrough, PaL ) );
    PeakValue = LastValue( HighestSince( Ref( iaTrough, -1 ), PaH , 1 ) );
    PeakIdx = LastValue( ValueWhen( PaH == PeakValue, Bi ) );
    TroughValue = LastValue( LowestSince( Ref( iaPeak, -1 ), PaL, 1 ) );
    TroughIdx = LastValue( ValueWhen( PaL == TroughValue, Bi ) );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

// Last leg
    if( Last_PeakIdx > Last_TroughIdx )
    {
        x0 = Last_PeakIdx;
        y0 = Last_PeakValue;
        x1 = TroughIdx;
        y1 = TroughValue;
        Line1 = LineDown = LineArray( x0, y0, x1, y1 );
        iaTrough[TroughIdx] = 1;
    }

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    if( Last_PeakIdx < Last_TroughIdx )
    {
        x0 = Last_TroughIdx;
        y0 = Last_TroughValue;
        x1 = PeakIdx;
        y1 = PeakValue;
        Line1 = LineUp = LineArray( x0, y0, x1, y1 );
        iaPeak[PeakIdx] = 1;
    }

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    iaZigZag = IIf( !IsEmpty( Line1 ), Line1, iaZigZag );
}

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

function Draw_UpLine( nGfxCoordsMode, nLine_Zorder, nUpLine_Color, nLine_Width, nLine_Style, nTroughBar_01, nTroughBarLow_01, nPeakBar_01, nPeakBarHigh_01 )
{
    GfxSetCoordsMode( nGfxCoordsMode );
    GfxSetZOrder( nLine_Zorder );

    GfxSelectPen( nUpLine_Color, nLine_Width, nLine_Style );
    GfxMoveTo( nTroughBar_01, nTroughBarLow_01 );
    GfxLineTo( nPeakBar_01, nPeakBarHigh_01 );
}

function Draw_DownLine( nGfxCoordsMode, nDownLine_Color, nLine_Zorder, nLine_Width, nLine_Style, nPeakBar_01, nPeakBarHigh_01, nTroughBar_01, nTroughBarLow_01 )
{
    GfxSetCoordsMode( nGfxCoordsMode );
    GfxSetZOrder( nLine_Zorder );

    GfxSelectPen( nDownLine_Color, nLine_Width, nLine_Style );
    GfxMoveTo( nPeakBar_01, nPeakBarHigh_01 );
    GfxLineTo( nTroughBar_01, nTroughBarLow_01 );
}

function Draw_UpLine_PT_SameBar( nGfxCoordsMode, nLine_Zorder, nLine_Color, nLine_Width, nLine_Style, nTroughBar_02, nTroughBarLow_02, nPeakBar_01, nPeakBarHigh_01 )
{
    GfxSetCoordsMode( nGfxCoordsMode );
    GfxSetZOrder( nLine_Zorder );

    GfxSelectPen( nLine_Color, nLine_Width, nLine_Style );
    GfxMoveTo( nTroughBar_02, nTroughBarLow_02 );
    GfxLineTo( nPeakBar_01, nPeakBarHigh_01 );
}

function Draw_DownLine_PT_SameBar( nGfxCoordsMode, nLine_Zorder, nLine_Color, nLine_Width, nLine_Style, nPeakBar_02, nPeakBarHigh_02, nTroughBar_01, nTroughBarLow_01 )
{
    GfxSetCoordsMode( nGfxCoordsMode );
    GfxSetZOrder( nLine_Zorder );

    GfxSelectPen( nLine_Color, nLine_Width, nLine_Style );
    GfxMoveTo( nPeakBar_02, nPeakBarHigh_02 );
    GfxLineTo( nTroughBar_01, nTroughBarLow_01 );
}

function Draw_Line_PT_SameBar_to_PT_SameBar( nGfxCoordsMode, nLine_Zorder, nLine_Color, nLine_Width, nLine_Style, nTroughBar_02, nTroughBarLow_02, nPeakBar_01, nPeakBarHigh_01 )
{
    GfxSetCoordsMode( nGfxCoordsMode );
    GfxSetZOrder( nLine_Zorder );

    GfxSelectPen( nLine_Color, nLine_Width, nLine_Style );
    GfxMoveTo( nTroughBar_02, nTroughBarLow_02 );
    GfxLineTo( nPeakBar_01, nPeakBarHigh_01 );
}

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

if( nZigZag_DisplaySwitch == 1 )
{
    nGfxCoordsMode = 1;
    nLine_Zorder = nZZ_Line_Zorder;

    nLine_Color = nZZ_UpLine_Color;
    nUpLine_Color = nZZ_UpLine_Color;
    nDownLine_Color = nZZ_DownLine_Color;
    nLine_Width = nZZ_Line_Width;
    nLine_Style = nGFX_Line_Style;

    for( i = 0; i < BarCount - 1; i++ )
    {
        if( nPeakTrough_SameBar_01[i] )
        {
            Draw_UpLine( nGfxCoordsMode, nLine_Zorder, nUpLine_Color, nLine_Width, nLine_Style, nTroughBar_01[i], nTroughBarLow_01[i], nPeakBar_01[i], nPeakBarHigh_01[i] );
        }

        if( nPeakTrough_SameBar_03[i] )
        {
            Draw_UpLine( nGfxCoordsMode, nLine_Zorder, nUpLine_Color, nLine_Width, nLine_Style, nTroughBar_01[i], nTroughBarLow_01[i], nPeakBar_01[i], nPeakBarHigh_01[i] );
        }

        if( nPeakTrough_SameBar_04[i] )
        {
            Draw_DownLine( nGfxCoordsMode, nDownLine_Color, nLine_Zorder, nLine_Width, nLine_Style, nPeakBar_01[i], nPeakBarHigh_01[i], nTroughBar_01[i], nTroughBarLow_01[i] );
        }

        if( nPeakTrough_SameBar_01[i] AND nRecent_Pivot_Trough[i] )
        {
            Draw_UpLine_PT_SameBar( nGfxCoordsMode, nLine_Zorder, nLine_Color, nLine_Width, nLine_Style, nTroughBar_02[i], nTroughBarLow_02[i], nPeakBar_01[i], nPeakBarHigh_01[i] );
        }

        if( nPeakTrough_SameBar_01[i] AND nRecent_Pivot_Peak[i] )
        {
            Draw_DownLine_PT_SameBar( nGfxCoordsMode, nLine_Zorder, nLine_Color, nLine_Width, nLine_Style, nPeakBar_02[i], nPeakBarHigh_02[i], nTroughBar_01[i], nTroughBarLow_01[i] );
        }

        if( nPeakTrough_SameBar_01[i] AND nPeakTrough_SameBar_02[i] )
        {
            Draw_Line_PT_SameBar_to_PT_SameBar( nGfxCoordsMode, nLine_Zorder, nLine_Color, nLine_Width, nLine_Style, nTroughBar_02[i], nTroughBarLow_02[i], nPeakBar_01[i], nPeakBarHigh_01[i] );
        }
    }
}

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

nZigZag = Calculate_ZigZag( nPeak, nTrough );
Calculate_LastSegment( nPeak, nTrough, nZigZag );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

if( nZigZag_DisplaySwitch == 1 )
{
    nZZ_Line_Color = IIf( nZigZag, nZZ_UpLine_Color, IIf( nZigZag, nZZ_DownLine_Color, Null ) );
    Plot( nZigZag, "", nZZ_Line_Color, nZZ_Line_Style, Null, Null, 0, nZZ_Line_Zorder, nZZ_Line_Width );
}

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

if( nZZ_PeakTrough_Shapes_DisplaySwitch )
{
    PlotShapes( nZZ_Peak_Shape_Type * nPeak, nZZ_Peak_Shape_Color, 0, High, nZZ_Peak_Shape_vPosition );
    PlotShapes( nZZ_Trough_Shape_Type * nTrough, nZZ_Trough_Shape_Color, 0, Low, nZZ_Trough_Shape_vPosition );
}

_SECTION_END();

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1 Like

As usual, this zigzag has many peaks and troughs, which may not be useful for everyone. One solution is to increase the fractal strength or to increase the fractal-strength-factor in the parameters. Another approach is to use another zigzag, the 'Prime-Zigzag,' which overlaps the 'Base-Zigzag.' The 'Prime-Zigzag' cannot be generated simply by using the HigherHigh and LowerLow of the Base-Zigzag or by duplicating the Base-Zigzag's fractal definition using SparseCompress approach. The following code should be appended below to the previous code to achieve this.



_SECTION_BEGIN( "Define pNeo-Fractals" );


pRightside_NeoFractal_Strength = Param( "Prime-Zigzag's Neo-Fractal Strength", 1, 1, 50, 1 );
pLeftside_NeoFractal_Strength = pRightside_NeoFractal_Strength; // Param( "pLeftside Neo-Fractal-Strength", 1, 0, 50, 1 );
pNeoFractal_Strength_Factor = Param( "Prime-Zigzag Neo-Fractal Strength-Factor", 1, 1, 20, 1 );

pRsNFS = pRightside_NeoFractal_Strength;
pLsNFs = pLeftside_NeoFractal_Strength;
pNFSF = pNeoFractal_Strength_Factor;

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

nPeak_High = ValueWhen( nPeak, PaH );
nTrough_Low = ValueWhen( nTrough, PaL );

Calculate_Main_Pivots( pLsNFs, pRsNFS, pNFSF, nPeak_High, nTrough_Low );

pUp_NeoFractal = iUp_NeoFractal;
pDown_NeoFractal = iDown_NeoFractal;

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

pPeak = pUp_NeoFractal;
pTrough = pDown_NeoFractal;

_SECTION_END();

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


_SECTION_BEGIN( "Find Missed pPeak-pTrough" );



// Find Missed Peak

pTrough_Bars = BarsSince( pTrough );
pHH_Bars = HHVBars( High, pTrough_Bars );      // Bars back to higher high since nTrough (if > 0, it is bars back to missed Peak)
pHH_Bars_Peak = IIf( pPeak, pHH_Bars, 0 );  // Restrict to current Peak bar
pHH_Bars_Peak_Reverse = Reverse( pHH_Bars_Peak );    // Can't change past so reverse time
pHH_Bars_Peak_Bars_Reverse = ValueWhen( pHH_Bars_Peak_Reverse, pHH_Bars_Peak_Reverse );   // Hold 'bars back to new Peak' forward in reversed time
pPeak_Bar_New_Reverse = Ref( pHH_Bars_Peak_Reverse, -pHH_Bars_Peak_Bars_Reverse ) == pHH_Bars_Peak_Bars_Reverse;  // Find new Peak bar in reversed time
pPeak_Bar_New = Reverse( pPeak_Bar_New_Reverse );    // Restore time direction

pPeak = ( pPeak OR pPeak_Bar_New ) AND NOT pHH_Bars_Peak;   // Add new Peak signal and remove old

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

// Find Missed Trough

pPeak_Bars = BarsSince( pPeak );
pLL_Bars = LLVBars( Low, pPeak_Bars );      // Bars back to lower low since nPeak (if > 0, it is bars back to missed Trough)
pLL_Bars_Trough = IIf( pTrough, pLL_Bars, 0 );  // Restrict to current Trough bar
pLL_Bars_Trough_Reverse = Reverse( pLL_Bars_Trough );    // Can't change past so reverse time
pLL_Bars_Trough_Bars_Reverse = ValueWhen( pLL_Bars_Trough_Reverse, pLL_Bars_Trough_Reverse );   // Hold 'bars back to new Trough' forward in reversed time
pTrough_Bar_New_Reverse = Ref( pLL_Bars_Trough_Reverse, -pLL_Bars_Trough_Bars_Reverse ) == pLL_Bars_Trough_Bars_Reverse;  // Find new Trough bar in reversed time
pTrough_Bar_New = Reverse( pTrough_Bar_New_Reverse );    // Restore time direction

pTrough = ( pTrough OR pTrough_Bar_New ) AND NOT pLL_Bars_Trough;   // Add new Trough signal and remove old


_SECTION_END();

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


_SECTION_BEGIN( "Clean pPeak-pTrough" );

// 'clean' the pivots function
// meaning make the pivots alternate like Peak-Trough-Peak-Trough-Peak-Trough-etc..

xpPeak = xpTrough = 0;

// run clean pivots
Alternate_PeakTrough( pPeak, pTrough );
pPeak = xnPeak_g;
pTrough = xnTrough_g;


_SECTION_END();

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


_SECTION_BEGIN( "pPivots-Camparision" );


for( i = 0; i < 3; i++ )
{
    VarSet( "pPeak_x" + i, ValueWhen( pPeak, Bi, i ) );
    VarSet( "pTrough_x" + i, ValueWhen( pTrough, Bi, i ) );
    VarSet( "pPeakHigh_" + i, ValueWhen( pPeak, PaH, i ) );
    VarSet( "pTroughLow_" + i, ValueWhen( pTrough, PaL, i ) );
}

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

pLowerLow = pTrough AND pTroughLow_1 < pTroughLow_2;           // LL = LowerLow
pHigherLow = pTrough AND pTroughLow_1 > pTroughLow_2;          // HL = HigherLow
pHigherHigh = pPeak AND pPeakHigh_1 > pPeakHigh_2;             // HH = HigherHigh
pLowerHigh = pPeak AND pPeakHigh_1 < pPeakHigh_2;              // LH = LowerHigh
pDoubleTop = pPeak AND pPeakHigh_1 == pPeakHigh_2;             // DT = DoubleTop
pDoubleBottom = pTrough AND pTroughLow_1 == pTroughLow_2;      // DB = DoubleBottom

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

pPeakBar_01 =  ValueWhen( pPeak, Bi, 1 );
pPeakBar_02 =  ValueWhen( pPeak, Bi, 2 );
pPeakBar_03 = ValueWhen( pPeak, Bi, 3 );
pTroughBar_01 = ValueWhen( pTrough, Bi, 1 );
pTroughBar_02 = ValueWhen( pTrough, Bi, 2 );
pTroughBar_03 = ValueWhen( pTrough, Bi, 3 );

pPeakBarHigh_01 =  ValueWhen( pPeak, PaH, 1 );
pPeakBarHigh_02 =  ValueWhen( pPeak, PaH, 2 );
pPeakBarHigh_03 =  ValueWhen( pPeak, PaH, 3 );
pTroughBarLow_01 = ValueWhen( pTrough, PaL, 1 );
pTroughBarLow_02 = ValueWhen( pTrough, PaL, 2 );
pTroughBarLow_03 = ValueWhen( pTrough, PaL, 3 );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

pLast_Pivot_Peak = pPeakBar_01 > pTroughBar_01;
pLast_Pivot_Trough = pTroughBar_01 > pPeakBar_01;

pRecent_Pivot_Peak = pPeakBar_02 > pTroughBar_02 AND pTroughBar_01 > pPeakBar_02;
pRecent_Pivot_Trough = pTroughBar_02 > pPeakBar_02 AND pPeakBar_01 > pTroughBar_02;

pPrevious_Pivot_Peak = pPeakBar_02 < pTroughBar_02 AND pTroughBar_02 < pPeakBar_01 AND pPeakBar_01 < pTroughBar_01;
pPrevious_Pivot_Trough = pTroughBar_02 < pPeakBar_02 AND pPeakBar_02 < pTroughBar_01 AND pTroughBar_01 < pPeakBar_01;

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

pPeakTrough_SameBar_01 = pPeakBar_01 == pTroughBar_01;
pPeakTrough_SameBar_02 = pPeakBar_02 == pTroughBar_02;
pPeakTrough_SameBar_03 = pPeakBar_02 == pTroughBar_01 AND pPeakBar_03 > pTroughBar_02;
pPeakTrough_SameBar_04 = pTroughBar_02 == pPeakBar_01 AND pTroughBar_03 > pPeakBar_02;


_SECTION_END();

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx



_SECTION_BEGIN( "pZigZag Pivot's Lables" );


//pPivot_Labels_DisplaySwitch = ParamToggle( "Display pPivot-Labels", "No|Yes", 1 );
pPivot_Labels_Zorder = Param( "pPivot-Label's Zorder", 5, -5, 5, 1 );
pPivot_Label_Background_Color = ParamColor( "pLabel's Background-Color", colorBlack );
pPivot_Upper_Label_Color = ParamColor( "pUpper-Label Color", colorYellow );
pPivot_Lower_Label_Color = ParamColor( "pLower-Lable Color", colorCustom11 );
pPivot_Upper_Label_vPosition = Param( "pUpper-Label's Vertical-Position", 30, 0, 100, 1 );
pPivot_Lower_Label_vPosition = Param( "pLower-Label's Vertical-Position", -30, 0, -100, 1 );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


if( pPivot_Labels_DisplaySwitch == 1 )
{
    GfxSetZOrder( pPivot_Labels_Zorder );

    for( i = 0; i < BarCount - 1; i++ )
    {
        if( pLowerLow[i] )
        {
            pString = "LL";
            PlotTextSetFont( pString, Font_Name, Text_Size, i, Low[i], pPivot_Lower_Label_Color, pPivot_Label_Background_Color, pPivot_Lower_Label_vPosition );
        }

        if( pHigherLow [i] )
        {
            pString = "HL";
            PlotTextSetFont( pString, Font_Name, Text_Size, i, Low[i], pPivot_Lower_Label_Color, pPivot_Label_Background_Color, pPivot_Lower_Label_vPosition );
        }

        if( pHigherHigh[i] )
        {
            pString = "HH";
            PlotTextSetFont( pString, Font_Name, Text_Size, i, High[i], pPivot_Upper_Label_Color, pPivot_Label_Background_Color, pPivot_Upper_Label_vPosition );
        }

        if( pLowerHigh[i] )
        {
            pString = "LH";
            PlotTextSetFont( pString, Font_Name, Text_Size, i, High[i], pPivot_Upper_Label_Color, pPivot_Label_Background_Color, pPivot_Upper_Label_vPosition );
        }

        if( pDoubleTop[i] )
        {
            pString = "DT";
            PlotTextSetFont( pString, Font_Name, Text_Size, i, High[i], pPivot_Upper_Label_Color, pPivot_Label_Background_Color, pPivot_Upper_Label_vPosition );
        }

        if( pDoubleBottom[i] )
        {
            pString = "DB";
            PlotTextSetFont( pString, Font_Name, Text_Size, i, Low[i], pPivot_Lower_Label_Color, pPivot_Label_Background_Color, pPivot_Lower_Label_vPosition );
        }
    }
}

_SECTION_END();

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx



_SECTION_BEGIN( "Prime-ZigZag" );


// pZigZag_DisplaySwitch = ParamToggle( "Display pZigZag ", "No|Yes", 1 );
// pZZ_PeakTrough_Shapes_DisplaySwitch = ParamToggle( "Display pZZ's PeakTrough-Shapes  ", "No|Yes", 0 );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

pZZ_Line_Zorder = Param( "pZZ Line-Zorder", 5, -5, 5, 1 );
pZZ_Line_Width = Param( "pZZ Line-Width", 3, 1, 5, 1 );
pZZ_Line_Style = ParamStyle( "pZZ Line-Style", styleLine | styleNoRescale | styleNoLabel );
pGFX_Line_Style = Param( "pGFX Line-Style", 0, 0, 5, 1 ); // Solid=0, Dash=1, Dot=2, Null=5 (Invisible-Pen).

pZZ_UpLine_Color = ParamColor( "pZZ's UpLine-Color", colorWhite );
pZZ_DownLine_Color =  ParamColor( "pZZ DownLine-Color", colorWhite );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

pZZ_Peak_Shape_Color = ParamColor( "pZZ Peak Shape-Color", colorCustom12 );
pZZ_Trough_Shape_Color = ParamColor( "pZZ Trough Shape-Color", colorYellow );

pZZ_Peak_Shape_Type = Param( "pZZ Peak Shape-Type", 13, 0, 50, 1 );
pZZ_Trough_Shape_Type = Param( "pZZ Trough Shape-Type", 13, 0, 50, 1 );

pZZ_Peak_Shape_vPosition = Param( "pZZ Peak-Shape's Vertical-Position", 10, 0, 100, 1 );
pZZ_Trough_Shape_vPosition = Param( "pZZ Trough-Shape's Vertical-Position", -10, 0, -100, 1 );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

ibPeak = ibTrough = 0;
ibZigZag = Null;

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

if( pZigZag_DisplaySwitch == 1 )
{
    pGfxCoordsMode = 1;
    pLine_Zorder = pZZ_Line_Zorder;

    pLine_Color = pZZ_UpLine_Color;
    pUpLine_Color = pZZ_UpLine_Color;
    pDownLine_Color = pZZ_DownLine_Color;
    pLine_Width = pZZ_Line_Width;
    pLine_Style = pGFX_Line_Style;

    for( i = 0; i < BarCount - 1; i++ )
    {
        if( pPeakTrough_SameBar_01[i] )
        {
            Draw_UpLine( pGfxCoordsMode, pLine_Zorder, pUpLine_Color, pLine_Width, pLine_Style, pTroughBar_01[i], pTroughBarLow_01[i], pPeakBar_01[i], pPeakBarHigh_01[i] );
        }

        if( pPeakTrough_SameBar_03[i] )
        {
            Draw_UpLine( pGfxCoordsMode, pLine_Zorder, pUpLine_Color, pLine_Width, pLine_Style, pTroughBar_01[i], pTroughBarLow_01[i], pPeakBar_01[i], pPeakBarHigh_01[i] );
        }

        if( pPeakTrough_SameBar_04[i] )
        {
            Draw_DownLine( pGfxCoordsMode, pDownLine_Color, pLine_Zorder, pLine_Width, pLine_Style, pPeakBar_01[i], pPeakBarHigh_01[i], pTroughBar_01[i], pTroughBarLow_01[i] );
        }

        if( pPeakTrough_SameBar_01[i] AND pRecent_Pivot_Trough[i] )
        {
            Draw_UpLine_PT_SameBar( pGfxCoordsMode, pLine_Zorder, pLine_Color, pLine_Width, pLine_Style, pTroughBar_02[i], pTroughBarLow_02[i], pPeakBar_01[i], pPeakBarHigh_01[i] );
        }

        if( pPeakTrough_SameBar_01[i] AND pRecent_Pivot_Peak[i] )
        {
            Draw_DownLine_PT_SameBar( pGfxCoordsMode, pLine_Zorder, pLine_Color, pLine_Width, pLine_Style, pPeakBar_02[i], pPeakBarHigh_02[i], pTroughBar_01[i], pTroughBarLow_01[i] );
        }

        if( pPeakTrough_SameBar_01[i] AND pPeakTrough_SameBar_02[i] )
        {
            Draw_Line_PT_SameBar_to_PT_SameBar( pGfxCoordsMode, pLine_Zorder, pLine_Color, pLine_Width, pLine_Style, pTroughBar_02[i], pTroughBarLow_02[i], pPeakBar_01[i], pPeakBarHigh_01[i] );
        }
    }
}

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

pZigZag = Calculate_ZigZag( pPeak, pTrough );
Calculate_LastSegment( pPeak, pTrough, pZigZag );

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

if( pZigZag_DisplaySwitch == 1 )
{
    pZZ_Line_Color = IIf( pZigZag, pZZ_UpLine_Color, IIf( pZigZag, pZZ_DownLine_Color, Null ) );
    Plot( pZigZag, "", pZZ_Line_Color, pZZ_Line_Style, Null, Null, 0, pZZ_Line_Zorder, pZZ_Line_Width );
}

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

if( pZZ_PeakTrough_Shapes_DisplaySwitch )
{
    PlotShapes( pZZ_Peak_Shape_Type * pPeak, pZZ_Peak_Shape_Color, 0, High, pZZ_Peak_Shape_vPosition );
    PlotShapes( pZZ_Trough_Shape_Type * pTrough, pZZ_Trough_Shape_Color, 0, Low, pZZ_Trough_Shape_vPosition );
}

_SECTION_END();

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1 Like

Thanks for the excellent Indicator.Can you please add the following option?

1.Option to plot the Price at Pivot High and Low Points with option to
turn off decimal as it will make the chart look cluttered

2.Option to measure the Swings in points and percentage

3.Option to measure Time in terms of numbers of bars in the swing.

Mr. @krisnara thanks for liking the indicator. My AFL knowledge isn’t good enough…still tomorrow I will try to code.

“…Option to turn off the decimal…”

This option is already provided in the code by using the below line:

nZZ_PeakTrough_Shapes_DisplaySwitch = ParamToggle( "Display ZZ's PeakTrough-Shapes", "No|Yes", 1 );

Please find this option in the parameters window near the top.

And for the solution to other things you requested, you can easily find out in Mr. @empottasch’s zigzag codes in this forum.

Still tomorrow I will try to find it myself for you and then after properly adding it to this AFL,I will share it to you

Thanks LotusHeart. I found that setting.

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.