i also have a version I made many years ago where I tried something like that, meaning to counts pivots that fall within a zone. The default code requires at least 4 points to fall within a certain zone. The zone width, number of points etc. are all variables you can adjust in the parameter settings. The default settings give the following result for the Oil daily chart (see below). If someone has ideas to improve it let me know.
rightstrength = Param( "Right Strength", 10, 2, 50, 1 );
leftstrength = Param( "Left Strength", 10, 2, 50, 1 );
nlevels = Param( "Number of Levels", 4, 0, 20, 1 );
atrmultiplier = Param( "ATR Multiplier", 0.25, 0, 10, 0.01 );
atrperiod = Param( "ATR Period", 50, 10, 200, 1 );
minpiv = Param( "Minimum number of Pivots inside ATR zone", 4, 2, 10, 1 );
zonedisplay = ParamToggle( "Display of Zone", "Cloud|Line", 1 );
pivnumberdisplay = ParamToggle( "Display Pivot Number in Zone", "Off|On", 1 );
GfxSetZOrder( -5 );
GfxSetCoordsMode( 1 );
GfxSelectPen( ColorRGB( 80, 80, 80 ), 2, 0 );
GfxSelectSolidBrush( ColorRGB( 30, 30, 30 ) );
ft = "Arial Black";
sz = 10;
bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );
pk = H == HHV( H, leftstrength ) AND Ref( HHV( H, rightstrength ), rightstrength ) < H;
tr = L == LLV( L, leftstrength ) AND Ref( LLV( L, rightstrength ), rightstrength ) > L;
for( i = 0; i < 4; i++ )
{
VarSet( "px" + i, ValueWhen( pk, bi, i ) );
VarSet( "tx" + i, ValueWhen( tr, bi, i ) );
VarSet( "ph" + i, ValueWhen( pk, H, i ) );
VarSet( "tl" + i, ValueWhen( tr, L, 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;
idxarray = ValueWhen( pk OR tr, bi, 1 );
SetChartBkColor( ColorRGB( 0, 0, 0 ) );
SetChartOptions( 0, chartShowArrows | chartShowDates );
Plot( C, "C", colorWhite, styleCandle, Null, Null, 0, 0, 1 );
PlotShapes( shapeSmallCircle * tr, ColorRGB( 0, 255, 0 ), 0, L, -10 );
PlotShapes( shapeSmallCircle * pk, ColorRGB( 255, 0, 0 ), 0, H, 10 );
function drawLevel( cnt, storageval, storageidx, cntlevels, valtop, valbot )
{
if( pivnumberdisplay )
{
clr1 = colorBlack;
clr2 = colorGold;
for( k = 0; k < cnt; k++ )
{
str = "" + ( k + 1 );
PlotTextSetFont( str, ft, sz, storageidx[k] - 1, valbot, clr1, clr2, -2 * sz );
}
}
x0 = storageidx[cnt - 1];
y0 = valbot;
x1 = storageidx[0];
y1 = valtop;
GfxRectangle( x0, y0, x1, y1 );
linetop = LineArray( x0, y1, x1, y1, 1 );
linebot = LineArray( x0, y0, x1, y0, 1 );
if( zonedisplay )
{
lineavg = IIf( !IsEmpty( linetop ) && !IsEmpty( linebot ), ( linetop + linebot ) / 2, Null );
lineavg = IIf( bi >= x1, lineavg, Null );
y1 = IIf( bi >= x1, y1, Null );
y0 = IIf( bi >= x1, y0, Null );
Plot( y0, "", IIf( lineavg > C, ColorRed, ColorGreen ), styleLine | styleNoLabel | styleNoRescale, Null, Null, 0, 0, 1 );
Plot( y1, "", IIf( lineavg > C, ColorRed, ColorGreen ), styleLine | styleNoLabel | styleNoRescale, Null, Null, 0, 0, 1 );
clr = LastValue( IIf( lineavg > C, ColorRed, ColorGreen ) );
avgval = ( y0 + y1 ) / 2;
PlotTextSetFont( "" + avgval, ft, sz, BarCount + 2, ( y0[BarCount - 1] + y1[BarCount - 1] ) / 2, colorWhite, clr, -sz / 2 );
}
else
{
lineavg = IIf( !IsEmpty( linetop ) && !IsEmpty( linebot ), ( linetop + linebot ) / 2, Null );
lineavg = IIf( bi >= x1, lineavg, Null );
y1 = IIf( bi >= x1, y1, Null );
y0 = IIf( bi >= x1, y0, Null );
PlotOHLC( y1, y1, y0, y0, "", IIf( lineavg > C, ColorRed, ColorGreen ), styleCloud | styleNoLabel | styleNoRescale, Null, Null, 0, 0, 1 );
clr = LastValue( IIf( lineavg > C, ColorRed, ColorGreen ) );
avgval = ( y0 + y1 ) / 2;
PlotTextSetFont( "" + avgval, ft, sz, BarCount + 2, ( y0[BarCount - 1] + y1[BarCount - 1] ) / 2, colorWhite, clr, -sz / 2 );
}
cntlevels += 1;
return cntlevels;
}
delta = atrmultiplier * Ref( ATR( atrperiod ), -1 );
cnt = 0;
storageval = 0;
storageidx = 0;
cntlevels = 0;
lpcnt = 0;
for( i = lvb; i > fvb; i-- )
{
if( pk[i] OR tr[i] )
{
if( pk[i] )
{
val = ph1[i];
valtop = val + delta[i];
valbot = val - delta[i];
nexti = idxarray[i - 1] + 1;
}
else
if( tr[i] )
{
val = tl1[i];
valtop = val + delta[i];
valbot = val - delta[i];
nexti = idxarray[i - 1] + 1;
}
storageval[0] = val;
storageidx[0] = i;
cnt = 1;
for( j = i - 1; j > fvb; j-- )
{
if( pk[j] && ph1[j] < valtop && ph1[j] > valbot )
{
storageval[cnt] = ph1[j];
storageidx[cnt] = px1[j];
cnt = cnt + 1;
j = idxarray[j - 1] + 1;
}
else
if( tr[j] && tl1[j] < valtop && tl1[j] > valbot )
{
storageval[cnt] = tl1[j];
storageidx[cnt] = tx1[j];
cnt = cnt + 1;
j = idxarray[j - 1] + 1;
}
}
// draw level
if( cnt >= minpiv )
{
cntlevels = drawLevel( cnt, storageval, storageidx, cntlevels, valtop, valbot );
str = "1";
}
i = nexti;
}
lpcnt = lpcnt + 1;
if( cntlevels >= nlevels ) break;
}