Loop I would like to avoid

bi = BarIndex();
foundSignals = 0;
foundSignalsAmount = 0;
for(i=0;i<=LastValue(bi);i++) { 
	if(mySignalLast[i] != 0) {
		foundSignals[foundSignalsAmount] = i-mySignalLastShift[i];
		foundSignalsAmount++;	
	}
}

I have got a loop in my code I would like to remove. Array mySignalLast has about 3 places where the value is not 0. I need to know the values and the index of the values. I am sure there is a other elegant way to find the indexes of some values in a array. Please help. Thanks in advance.

bi = BarIndex();
qfdb = Status("quickaflfirstdatabar");

function MxValuesAtSignal(sig) {
	/// @link https://forum.amibroker.com/t/loop-i-would-like-to-avoid/16828/2
	/// by fxshrat
	local col, mat, spc, spi, spcond, values;
	values = IIf(sig, C, Null);
	spcond = NOT IsNull(values);
	spc = SparseCompress(spcond, values);
	spi = SparseCompress(spcond, /*qfdb +*/ bi);

	mat = Matrix(2, BarCount);
	col = MxGetSize(mat, 1)-1;
	mat = MxSetBlock(mat, 0, 0, 0, col, spc);
	mat = MxSetBlock(mat, 1, 1, 0, col, spi);
	mat = MxGetBlock(mat, 0, 1, Min(NullCount(spc), col), col);
	return mat;
}

mySignalLast = Cross(C, MA(C, 200));

mat = MxValuesAtSignal(mySignalLast);
MxToString(mat);

Plot( C, "Price", colorDefault, styleBar );
PlotShapes( mySignalLast * shapeUpArrow, colorGreen, layer = 0, L, -12 );

9

4 Likes

@firstmichal, so consuming only and going on to next stage?

Thanks It definitely answered my question.

HI fxshrat

firstmichal, so consuming only and going on to [next stage]?

What is the meaning of your question?

Hallo I now created a reduced version which is less complicated. Avoiding the matrix stuff, which made me problems when the original array was empty.

bi = BarIndex();
foundSignals = 0;
foundSignalsAmount = 0;

mySignalLastCompressIndex = SparseCompress(mySignalLastShift != 0, bi);

for(k=NullCount(mySignalLastCompressIndex); k<BarCount; k++) { 
	i = mySignalLastCompressIndex[k];
	foundSignals[foundSignalsAmount] = i-mySignalLastShift[i];
	foundSignalsAmount++;	
}

What you say is incorrect.
There is no problem (error message) when "original" array becomes empty (NULL);
If mySignalLast is Null then Matrix is Null (spcond becomes zero -> spc and spi become Null).

9

Same applies if there is no signal (zero array) then spcond returns zero array too.
And spc and spi become Null array and Nullcount becoming length Barcount.

10

Adding Min(NullCount(spc), col) as in 2nd post prevents error! Also NullCount does not become negative. Range of NullCount is from zero to BarCount.

So there is zero problem and nothing complicated.
Task was... creating custom array avoiding loop.

More simplified (adding spcond is not required):

bi = BarIndex();
qfdb = Status("quickaflfirstdatabar");

function MxValuesAtSignal(sig) {
	/// @link https://forum.amibroker.com/t/loop-i-would-like-to-avoid/16828/8
	/// by fxshrat
	local col, mat, spc, spi;
	spc = SparseCompress(sig, C);
	spi = SparseCompress(sig, /*qfdb +*/ bi);

	mat = Matrix(2, BarCount, Null);
	col = MxGetSize(mat, 1)-1;
	mat = MxSetBlock(mat, 0, 0, 0, col, spc);
	mat = MxSetBlock(mat, 1, 1, 0, col, spi);
	mat = MxGetBlock(mat, 0, 1, Min(NullCount(spc), col), col);
	return mat;
}

mySignalLast = Cross(C, MA(C, 200));//Null;//

mat = MxValuesAtSignal(mySignalLast);
MxToString(mat);
if ( mat )	printf( "#Signals: %g", MxGetSize(mat, 1) );

Plot( C, "Price", colorDefault, styleBar );
PlotShapes( mySignalLast * shapeUpArrow, colorGreen, layer = 0, L, -12 );
1 Like