What I was hoping to do is Consolidating Key Levels close to each other into one. This code somewhat works but really slows it down. Obviously because of the FOR loops. I was hoping to get a better way to identify "stronger" Key Levels based on the number of times it was "touched" using 1 minute timeframe and intraday.
function CheckNear( val1, val2, per )
{
per = per / 100;
nearIT = ( abs ( val1 - val2 ) ) / val2;
result = IIf ( nearIT <= per, True, False );
return result;
}
_SECTION_BEGIN("Study Space");
lo40 = L <= LLV( L, 40 );
//PlotShapes( lo40 * shapeSmallCircle, colorYellow, 0, L, -10 );
//"Total LLv = " + Sum( lo40, 150 );
//"valueWhen LOW = " + ValueWhen( lo40, L, 4 );
s = LastValue( Sum( lo40, 150 ) );
for( i = 1, loCnt = 0; i <= s ; i++ ) {
for( ii = 1; ii <= s; ii++ ) {
if( CheckNear( LastValue( ValueWhen( lo40, L , i ) ), LastValue( ValueWhen( lo40, L, ii ) ), .5 ) ){
loCnt[ i ]++;
loVal[ i ] = ( LastValue( ValueWhen( lo40, L, i ) ) + LastValue( ValueWhen( lo40, L, ii ) ) ) / 2;
}
}
if( loCnt[ i ] >= 2 ) {
//_TRACE( "loCnt[ " + i + " ] = " + loCnt[ i ] + " ** loVal[ " + i + " ] = " + loVal[ i ] );
Plot( ValueWhen( L == loVal[ i ], loVal[ i ] ), "Support", colorAqua, styleLine | styleNoLabel );
}
}
_SECTION_END();
You are adding up the last 150 array positions and using as the for() limit.
Anyway, I would do this on a very different way.
I would store all the levels on another array, using for(). I don't see any other way.
I would sort() this new array (that is not necessary in your code because your levels would be ascending or descending).
Run a for on the new array checking if they are near each other.
Can you try that on your own or some code would help?
I might have the time on this afternoon.
It is not a final code, it is just to show the idea.
Please, take a look at the comments.
_SECTION_BEGIN( "Study Space 2" );
function CheckNear( val1, val2, per )
{
per = per / 100;
nearIT = ( abs( val1 - val2 ) ) / val2;
// result = IIf( nearIT <= per, True, False ); // Wrong IIF() is for arrays, it is not a one-line IF()
result = nearIT <= per;
return result;
}
toGo = Param("(0=all) Last X Levels:", 30, 0, 1000);
if(toGO==0) toGO = BarCount-2;
Show = ParamToggle( "Show", "No|Yes", 0 );
if( Show )
{
// lo40 = L <= LLV( L, 40 ); // You need better levels, this condition will be TRUE for a number of near candles
lo40 = L <= LLV( L, 40 ) AND Ref( LLV( L, 5), 5 ) >= L; // This way L most be lower than the previous 40 but also lower than the next 5 bars, just one idea
BarI = BarIndex();
Title = ""; // You can use Title as a Debug, good for fast and small verifications
for( Total_Levels = 1; Total_Levels <= toGO; Total_Levels++ )
{
x1 = LastValue( ValueWhen( lo40, BarI, Total_Levels ) ); // Locate the previous Lo40 on a very fast way (and get its BarNumber)
if( x1 == 0 ) break; // All Levels were scanned
Levels_lo[Total_Levels-1] = Low[x1]; // Array Levels_lo will get all levels
//Title += "\n"+ (Total_Levels-1)+" - "+Levels_lo[Total_Levels-1];
}
Total_Levels--;
Title += "\n\nTotal Levels_H Gathered:" + Total_Levels;
// Levels_lo = Sort( Levels_lo, 0, Total_Levels, 0 ); // Sort array in ascending order, not needed for your code. Right?
/*
Title = "";
for( i = 0; i<Total_Levels ; i++ )
{
Title += "\n"+ i +" - "+Levels_lo[i];
}
*/
//
// Let's check if the levels are near each other
//
Checked = 0;
Checked_lo[0] = Levels_lo[0];
//Title += "\n"+Levels_lo[0];
for( i = 1; i <= Total_Levels ; i++ )
{
if( CheckNear( Checked_Lo[Checked] , Levels_lo[i], 0.5 ) )
{
//Title += "\n"+Checked+" Near:" + Checked_lo[Checked] + " and " + Levels_lo[i] + " ---> "+ ((Checked_lo[Checked] + Levels_lo[i]) / 2);
Checked_lo[ checked ] = (Checked_lo[Checked] + Levels_lo[i]) / 2;
}
else
{
//Title += "\n"+Checked+" Not Near:" + Checked_lo[Checked] + " and " + Levels_lo[i];
Checked++;
Checked_lo[ checked ] = Levels_lo[i];
}
}
//Title = "Checked:" + Checked + " - last:"+Checked_lo[Checked-1];
for( i = 0; i <= Checked ; i++ )
{
Plot( Checked_lo[i], "", colorAqua, styleLine | styleNoLabel | styleNoRescale );
}
}
_SECTION_END();
Your commented statement "Wrong IIF() is for arrays" is incorrect. IIf() function is polymorph. So it is for arrays as well as for numbers.
e.g.
var = Iif(element[ i ] > 0, 1, 0);// result is type number here
There is no loop required for that (custom array Levels_lo). Also ValueWhen being iterated thousands of times is much too slow. Instead look at SparseCompress and other additional functions.
Again... not any single loop required.
Rather use Gfx* functions here. Plot() is rather for arrays and you will get warning at 500 Plot() calls anyway.