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 );
}
}
}