Pivots & trend structure

7 functions

ZIG(K, N)

Zig-zag line on price type K reversing after an N% move. K: 0 open, 1 high, 2 low, 3 close.

The last leg repaints as new bars arrive — that is inherent to zig-zag, not a bug.

K(integer)
Which price to track: 0 open, 1 high, 2 low, 3 close.
N(float)
Reversal threshold in percent — a move smaller than this does not turn the line.
// 5% zig-zag on closes
ZIGLINE: ZIG(3, 5), COLORYELLOW;

// a larger threshold keeps only the major swings
MAJOR: ZIG(3, 12), COLORLIBLUE, LINETHICK2;
PEAK(K, N, M)

Value of the M-th most recent zig-zag peak.

K(integer)
Which price the zig-zag runs on: 0 open, 1 high, 2 low, 3 close.
N(float)
Reversal threshold in percent.
M(integer)
Which peak, counting back — 1 is the most recent.
// the last two swing highs
P1: PEAK(3, 5, 1), COLORGRAY, DOTLINE;
P2: PEAK(3, 5, 2), COLORGRAY, DOTLINE;

// lower high — the shape behind a bearish divergence
LOWERHIGH: P1 < P2;
PEAKBARS(K, N, M)

Bars from the M-th most recent peak to the current bar.

K(integer)
Which price the zig-zag runs on.
N(float)
Reversal threshold in percent.
M(integer)
Which peak, counting back.
// how long ago each swing high formed — pair it with PEAK
// to draw a line between the two highs
AGE1 := PEAKBARS(3, 5, 1);
AGE2 := PEAKBARS(3, 5, 2);
DRAWLINE(BARPOS = TOTALBARSCOUNT - AGE2, PEAK(3, 5, 2),
         BARPOS = TOTALBARSCOUNT - AGE1, PEAK(3, 5, 1), 1), COLORYELLOW;
TROUGH(K, N, M)

Value of the M-th most recent zig-zag trough.

K(integer)
Which price the zig-zag runs on.
N(float)
Reversal threshold in percent.
M(integer)
Which trough, counting back — 1 is the most recent.
// higher low against a falling oscillator — bullish divergence
T1 := TROUGH(3, 5, 1);
T2 := TROUGH(3, 5, 2);
DIVERGE: T1 > T2 AND MACD < REF(MACD, PEAKBARS(3, 5, 1));
TROUGHBARS(K, N, M)

Bars from the M-th most recent trough to the current bar.

K(integer)
Which price the zig-zag runs on.
N(float)
Reversal threshold in percent.
M(integer)
Which trough, counting back.
// a leg that has run for a while is more likely to be
// mature than one that just turned
LEGLEN: TROUGHBARS(3, 5, 1);
YOUNG: LEGLEN < 10;
SAR(N, STEP, MAXSTEP)

Parabolic SAR over an N-bar window, acceleration STEP capped at MAXSTEP (both in percent).

N(integer)
Window length used to seed the first stop.
STEP(float)
Acceleration per new extreme, in percent — 2 means 0.02.
MAXSTEP(float)
Cap on the acceleration, in percent — 20 means 0.20.
// the standard 0.02 / 0.20 parabolic, drawn as dots
SAR: SAR(10, 2, 20), CIRCLEDOT, COLORYELLOW;

// price above the dots is the long side
LONG: CLOSE > SAR;
SARTURN(N, STEP, MAXSTEP)

1 where SAR flips up, −1 where it flips down, 0 otherwise.

N(integer)
Window length used to seed the first stop.
STEP(float)
Acceleration per new extreme, in percent.
MAXSTEP(float)
Cap on the acceleration, in percent.
// the flip bars only — cleaner than comparing SAR to price
// on every bar, because it fires exactly once per turn
TURN := SARTURN(10, 2, 20);
DRAWICON(TURN = 1,  LOW,  85);
DRAWICON(TURN = -1, HIGH, 97);