Yet another ZigZag

so many zigzag functions, Percentage, ATR, Gann, Fractal. I wanted to add another 1 using HHV and LLV. Seems to be working good. Just wrote this yesterday so might still change a bit. But I did a playback and seems good. See also the parameter window to change the settings

nbar = Param( "Swing number of Bars", 10, 1, 50, 1 );
priceswitch = ParamToggle( "Use Close or High and Low price", "Use Close|Use High and Low", 1 );
showTrailline = ParamToggle( "Show Trail Line", "Off|On", 0 );
showprimarypivotlabels = ParamToggle( "Show Primary Pivot Labels", "Off|On", 0 );
// this toggle is for when in H/L mode the high is above res and the low below sup. There are 2 ways to handle this.
handleBothOutside = ParamToggle( "Long AND Short signal at the SAME bar", "Change Trend|Stay with current Trend", 0 );

bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );
pk = tr = 0;
ZigZag = line1 = Null;

if( priceswitch )
{
    prch = H;
    prcl = L;
    mode = "High/Low price";
}
else
{
    prch = C;
    prcl = C;
    mode = "Close price";
}

function calculateZigZag()
{
    zigup = Flip( tr, pk );
    zigupLow = ValueWhen( tr, prcl, 1 );
    zigupHigh = ValueWhen( pk, prch, 0 );
    zigupLowIndex = ValueWhen( tr, bi, 1 );
    zigupHighIndex = ValueWhen( pk, bi, 0 );
    slopeup = IIf( zigup, ( zigupHigh - zigupLow ) / ( zigupHighIndex - zigupLowIndex ) , Null );
    zigupLine = IIf( zigup, zigupLow + slopeup * BarsSince( tr ), Null );

    zigdn = Flip( pk, tr );
    zigdnLow = ValueWhen( tr, prcl, 0 );
    zigdnHigh = ValueWhen( pk, prch, 1 );
    zigdnLowIndex = ValueWhen( tr, bi, 0 );
    zigdnHighIndex = ValueWhen( pk, bi, 1 );
    slopedn = IIf( zigdn, ( zigdnLow - zigdnHigh ) / ( zigdnLowIndex - zigdnHighIndex ) , Null );
    zigdnLine = IIf( zigdn, zigdnHigh + slopedn * BarsSince( pk ), Null );

    ZigZag = IIf( zigup, zigupLine, IIf( zigdn, zigdnLine, Null ) );
    ZigZag = IIf( bi > Max( LastValue( ValueWhen( tr, bi ) ), LastValue( ValueWhen( pk, bi ) ) ), Null, ZigZag );
}
function calculateLastSegments()
{
    lastidxpk = LastValue( ValueWhen( pk, bi ) );
    lastidxtr = LastValue( ValueWhen( tr, bi ) );
    lastvalpk = LastValue( ValueWhen( pk, prch ) );
    lastvaltr = LastValue( ValueWhen( tr, prcl ) );
    valpk = LastValue( HighestSince( Ref( tr, -1 ), prch , 1 ) );
    idxpk = LastValue( ValueWhen( prch == valpk, bi ) );
    valtr = LastValue( LowestSince( Ref( pk, -1 ), prcl, 1 ) );
    idxtr = LastValue( ValueWhen( prcl == valtr, bi ) );

    if( lastidxpk > lastidxtr )
    {
        x0 = lastidxpk;
        y0 = lastvalpk;
        x1 = idxtr;
        y1 = valtr;
        line1 = linedn = LineArray( x0, y0, x1, y1 );
        tr[idxtr] = 1;
        valpk = LastValue( HighestSince( Ref( tr, -1 ), prch, 1 ) );
        idxpk = LastValue( ValueWhen( prch == valpk, bi ) );
    }

    if( lastidxpk < lastidxtr )
    {
        x0 = lastidxtr;
        y0 = lastvaltr;
        x1 = idxpk;
        y1 = valpk;
        line1 = lineup = LineArray( x0, y0, x1, y1 );
        pk[idxpk] = 1;
        valtr = LastValue( LowestSince( Ref( pk, -1 ), prcl, 1 ) );
        idxtr = LastValue( ValueWhen( prcl == valtr, bi ) );
    }

    ZigZag = IIf( !IsEmpty( line1 ), line1, ZigZag );
}

// find trend
res = HHV( prch, nbar );
sup = LLV( prcl, nbar );
crossup = prch > Ref( res, -1 );
crossdn = prcl < Ref( sup, -1 );

if( handleBothOutside )
{
    // if in H/L mode both crossup and crossdn at the same bar may occur.
    // if handleBothOutside is true then it will stay in the current trend
    // if handleBothOutside is false it will change the trend.
    crossup = IIf( ( crossup AND crossdn ) AND( BarsSince( Ref( crossup, -1 ) ) > BarsSince( Ref( crossdn, -1 ) ) ), 0, crossup );
    crossdn = IIf( ( crossup AND crossdn ) AND( BarsSince( Ref( crossdn, -1 ) ) > BarsSince( Ref( crossup, -1 ) ) ), 0, crossdn );
}

crossup = ExRem( crossup, crossdn );
crossdn = ExRem( crossdn, crossup );
trendup = Flip( crossup, crossdn );
trenddn = Flip( crossdn, crossup );

// find pivots
rtrenddn = Reverse( trenddn );
rtrendup = Reverse( trendup );
l1 = LowestSince( trenddn AND Ref( trendup, -1 ), prcl );
rL = Reverse( prcl );
l2 = LowestSince( rtrenddn AND Ref( rtrendup, -1 ), rL );
rl2 = Reverse( l2 );
h1 = HighestSince( trendup AND Ref( trenddn, -1 ), prch );
rH = Reverse( prch );
h2 = HighestSince( rtrendup AND Ref( rtrenddn, -1 ), rH );
rh2 = Reverse( h2 );
tr = l1 == rl2 AND trenddn;
pk = h1 == rh2 AND trendup;
rpk = Reverse( pk );
rtr = Reverse( tr );
rpk = ExRem( rpk, rtr );
rtr = ExRem( rtr, rpk );
pk = Reverse( rpk );
tr = Reverse( rtr );

calculateZigZag();
calculateLastSegments();

SetChartBkColor( ColorRGB( 0, 0, 0 ) );
SetChartOptions( 0, chartShowArrows | chartShowDates );
Plot( C, "Price", colorWhite, styleCandle, Null, Null, 0, 0, 0 );

if( showtrailline )
{
    if( priceswitch )
    {
        bp = Max( O, Ref( res, -1 ) );
        sp = Min( O, Ref( sup, -1 ) );
    }
    else
    {
        bp = C;
        sp = C;
    }

    Plot( IIf( trendup, sup, Null ), "", colorGreen, styleStaircase | styleNoRescale, Null, Null, 0, 0, 1 );
    Plot( IIf( trenddn, res, Null ), "", colorRed, styleStaircase | styleNoRescale, Null, Null, 0, 0, 1 );
    PlotShapes( IIf( trendup AND Ref( trenddn, -1 ), shapeSmallCircle, shapeNone ), colorWhite, 0, bp, 0 );
    PlotShapes( IIf( trenddn AND Ref( trendup, -1 ), shapeSmallCircle, shapeNone ), colorWhite, 0, sp, 0 );
}

Plot( zigzag, "ZigZag", colorGold, styleLine | styleNoLabel | styleNoRescale, Null, Null, 0, 1, 1 );
PlotShapes( IIf( tr, shapeSmallCircle, shapeNone ), colorGreen, 0, L, -10 );
PlotShapes( IIf( pk, shapeSmallCircle, shapeNone ), colorRed, 0, H, 10 );

if( showprimaryPivotLabels )
{
    ft = "Arial Black";
    sz = 8;
    clr = colorDefault;

    for( i = 0; i < 3; i++ )
    {
        VarSet( "px" + i, ValueWhen( pk, bi, i ) );
        VarSet( "tx" + i, ValueWhen( tr, bi, i ) );
        VarSet( "ph" + i, ValueWhen( pk, prch, i ) );
        VarSet( "tl" + i, ValueWhen( tr, prcl, i ) );
    }

    ll = tr AND tl1 < tl2;
    hl = tr AND tl1 > tl2;
    hh = pk AND ph1 > ph2;
    lh = pk AND ph1 < ph2;
    dt = pk AND ph1 == ph2;
    db = tr AND tl1 == tl2;

    str1 = "";

    for( i = fvb; i <= lvb; i++ )
    {
        if( pk[i] )
        {
            if( dt[i] )
                str1 = "DT";
            else
                if( hh[i] )
                    str1 = "HH";
                else
                    if( lh[i] )
                        str1 = "LH";

            PlotTextSetFont( str1, ft, sz, i, H[i], colorRed, clr, sz * 3 );
        }

        if( tr[i] )
        {
            str1 = "";

            if( db[i] )
                str1 = "DB";
            else
                if( ll[i] )
                    str1 = "LL";
                else
                    if( hl[i] )
                        str1 = "HL";

            PlotTextSetFont( str1, ft, sz, i, L[i], colorBlue, clr, -sz * 4 );
        }
    }
}
13 Likes

code is based on code I found here:
https://www.tradingview.com/script/vkAechsb/

But I expanded on the idea and I use either the Close or the High and Low price. I like the pivots it find very much. The direct translation of the TV code is here:

// https://www.tradingview.com/script/vkAechsb/
no = Param( "Swing", 3, 1, 50, 1 );

res = HHV( High, no );
sup = LLV( Low, no );

avd = IIf( Close > Ref( res, -1 ), 1, IIf( Close < Ref( sup, -1 ), -1, 0 ) );
avn = ValueWhen( avd, avd );
tsl = IIf( avn == 1, sup, res );
colr = IIf( Close >= tsl, colorGreen, IIf( Close <= tsl, colorRed,  colorLightGrey ) );

Buy = Cross( C, tsl );
Sell = Cross( tsl, C );
Buy = ExRem( Buy, Sell );
Sell = ExRem( Sell, Buy );
BuyPrice = SellPrice = C;

SetChartBkColor( ColorRGB( 0, 0, 0 ) );
SetChartOptions( 0, chartShowArrows | chartShowDates );
Plot( C, "Price", colorWhite, styleCandle, Null, Null, 0, 0, 0 );
Plot( tsl, "TSL", colr, styleLine, Null, Null, 0, 0, 1 );

PlotShapes( IIf( Buy, shapeSmallUpTriangle, shapeNone ), colorAqua, 0, L, -20 );
PlotShapes( IIf( Buy, shapeSmallCircle, shapeNone ) , colorAqua, 0, BuyPrice, 0 );
PlotShapes( IIf( Sell, shapeSmallDownTriangle, shapeNone ), colorGold, 0, H, -20 );
PlotShapes( IIf( Sell, shapeSmallCircle, shapeNone ), colorGold, 0, SellPrice, 0 );

4 Likes