Sorry to bother you again. My chat's scale is not in alignment with your code. Everything has compressed towards the upperside of chart. Please check the code and snapshot. Neither I have been able to find the place to insert the zigzag's pk (peak) and tr (trough) values.
_SECTION_BEGIN( "Empottasch-ZiZag" );
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();
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", colorAqua, styleLine | styleNoLabel | styleNoRescale, Null, Null, 0, 1, 2 );
//PlotShapes( IIf( tr, shapeSmallCircle, shapeNone ), colorGreen, 0, L, -10 );
//PlotShapes( IIf( pk, shapeSmallCircle, shapeNone ), colorRed, 0, H, 10 );
_SECTION_END();
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
_SECTION_BEGIN( "Fxshrat-Lines" );
fxshrat_Line_Zorder = Param( "fxshrat's Line Zorder", 1, -5, 5, 1 );
function fxMxStopLines(sig, targetarray, visi_chart) {
/// @link https://forum.amibroker.com/t/plot-horizontal-line-until-crossed/10802/32
/// by fxshrat@gmail.com
bir = Status("barvisible");// chart area array
if ( visi_chart ) {
Cum_s = Cum(IIf(bir, sig, 0));
lastcum = LastVisibleValue(Cum_s);
} else {
Cum_s = Cum(sig);
lastcum = LastValue(Cum_s, 1);
}
stop_mat = Matrix(3, Max(1,lastcum), 0);
colnum = MxGetSize(stop_mat, 1);
draw_range = IIf( visi_chart, bir, 1);
lastbar = BarCount-1;
for ( i = 0, n = 0; i < BarCount; i++ ) {
if ( draw_range[i] ) { // if visible chart
if ( sig[i] ) { // if signal
if ( n < colnum ) { // ensure not exceeding mat size
stop_mat[0][n] = i; // start bar
stop_mat[1][n] = lastbar; // end bar
stop_mat[2][n] = targetarray[i]; // level
for ( j = i+1, k = 0; j < BarCount; j++ ) {
if ( L[j] < stop_mat[2][n] ) {
stop_mat[1][n] = j; // end bar
break;
}
}
}
n++;
}
}
}
return stop_mat;
}
Version(6.0);
//RequestTimedRefresh( 1 );
SetChartOptions( 0, chartShowDates | chartShowArrows | chartWrapTitle );
_N( Title = StrFormat( "{{NAME}} - {{INTERVAL}} - {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%), Vol %g {{VALUES}}",
O, H, L, C, SelectedValue( ROC( C, 1 ) ), V ) );
Plot( C, "", colorDefault, styleBar );
GfxSetZOrder( fxshrat_Line_Zorder );
GfxSetCoordsMode( 1 );
GfxSetBkMode(1);
GfxSetTextAlign(0|0);
GfxSelectFont("Arial", 8, 500 );
GfxSetTextColor( colorLightYellow );
GfxSetBkColor(colorRed);
GfxSelectPen(colorRed, 1, 2);
percent_change = 2; //edit percent change
targetarray = Trough(L, percent_change);//tlas-stopvalue;
max_bars = 100; // edit maximum number of periods of line to be drawn
draw_all_lines = True;
draw_label = True;
visichart = true;
stop_mat = fxMxStopLines(L == targetarray, targetarray, visichart);
lastbar = BarCount-1;
colnum = MxGetSize(stop_mat, 1);
for ( n = 0; n < colnum; n++ ) {
x2 = stop_mat[1][n];
if ( x2 == lastbar OR draw_all_lines ) {
x1 = stop_mat[0][n];
if ( x2-x1 <= max_bars ) {
y = stop_mat[2][n];
GfxMoveTo(x1, y);
GfxLineTo(x2, y);
if ( draw_label) {
GfxTextOut(StrFormat("%g", y), x1, y );
GfxTextOut(StrFormat("%g bars", x2-x1), (x1+x2)*0.5, y );
}
}
}
}
/// ....
printf( "\n%s", MxToString(stop_mat));
printf( "\n#lines: %g, BarCount: %g", MxGetSize(stop_mat,1), BarCount );
_SECTION_END();
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx