Simple Step Sequencer Function

I created this function that produces result array from a completion of a sequence of 2 to 3 steps conditions. It also can have delay bars between Steps.
You can use this function when you have a series of conditions in sequence that you want to have in array variable when they completed.
The resulted array only returns 1 if all steps completed and 0 if for current bar no sequence completed.

My goal with this post is to improve its speed by means of converting parts to Amibroker arrays. I would like to see if possible to have the same functionality but with some loops converted to AFL array to improve performance.

Here is the Function:
function SequenceSteps(NumStep,Step1,Step1Reset,Step1BarDelay,Step2,Step2Reset,Step2BarDelay,Step3,Step3Reset)
{
** //returns array=1 when sequence completed**
** //Step1BarDelay => Delay means to wait X bars to check next Step condition, **
** // Ex. If = 0 then check in current bar all,Ex. If = 1 then wait 1 bar and check step 2**
** //nStep = NumStep;**
** active=0; //set Step ocurred flags**
** res=0;**
** BarDelay=0;**
** for( i = 0; i < BarCount; i++ )**
** {**
** if (Step1[i]==1) { active[1]=1; } //set event for step ocurred **
** if (Step1Reset[i]==1) { active[1]=0; BarDelay=0; }**
** if ((active[1]==1) AND (BarDelay[1]==Step1BarDelay)) //check step1 active and bar delay before next step**
** {**
** if (Step2[i]==1) { active[2]=1; } //set event for step ocurred**
** if (Step2Reset[i]==1) { active[2]=0;}**
** if ((active[2]==1) AND (BarDelay[2]==Step2BarDelay)) **
** {**
** if (Step3[i]==1) {active[3]=1;}**
** if (Step3Reset[i]==1) {active[3]=0;}**


** }**
** if (Step2[i]==1) //Step2 increment bar delay**
** {**
** if ((Step2BarDelay>0) AND (BarDelay[2]<Step2BarDelay)) {BarDelay[2]++;} //set bar delay count**
** }**
** }**
** finalStep=0;**
** switch( NumStep )**
** {**
** case 1:**
** finalStep=active[1]; **
** break;**

** case 2:**
** finalStep=active[2];**
** break;**


** case 3:**
** finalStep=active[3];**
** break;**
** }**


** if (Step1[i]==1) //Step1 increment bar delay**
** { **
** if ((Step1BarDelay>0) AND (BarDelay[1]<Step1BarDelay)) {BarDelay[1]++;} //set bar delay count**
** }**
** //las Step defined by "NumStep" sets when sequence completed**
** if (finalStep==1)**
** {**
** res[i]=1;**
** active=0; //clear active flags array**
** BarDelay=0; //clear array used for bar delay checks**
** }**
** }**
** return res;**
}

//Usage or call to Function is something like (the steps are for example):
//sequence with 2 steps
e1=Cross(MA(price,10),price); //step1
e1reset =0;
e2=Cross(MA(price,20),price) //step2
e3=0;
StepsCNT = 2; //steps can be 2 or 3 to have a real sequence
seqs1 = SequenceSteps(StepsCNT,e1,e1reset,0,e2,0,0,e3,0);
Buy = seqs1; //no real trading here just for demo of code

Here is the code properly formatted as per Forum rules.

function SequenceSteps(NumStep,Step1,Step1Reset,Step1BarDelay,Step2,Step2Reset,Step2BarDelay,Step3,Step3Reset)
{
	//returns array=1 when sequence completed
	//Step1BarDelay => Delay means to wait X bars to check next Step condition, 
	//      Ex. If = 0 then check in current bar all,Ex. If = 1 then wait 1 bar and check step 2
	//nStep = NumStep;
	active=0; //set Step ocurred flags
	res=0;
	BarDelay=0;
	for( i = 0; i < BarCount; i++ )
	{
	  if (Step1[i]==1) { active[1]=1; } //set event for step ocurred 
	  if (Step1Reset[i]==1) { active[1]=0; BarDelay=0; }
	  if ((active[1]==1) AND (BarDelay[1]==Step1BarDelay))  //check step1 active and bar delay before next step
	  {
		if (Step2[i]==1) { active[2]=1; } //set event for step ocurred
		if (Step2Reset[i]==1) { active[2]=0;}
		if ((active[2]==1) AND (BarDelay[2]==Step2BarDelay)) 
		{
		   if (Step3[i]==1) {active[3]=1;}
		   if (Step3Reset[i]==1) {active[3]=0;}
		   
		}
		if (Step2[i]==1) //Step2 increment bar delay
		{
			if ((Step2BarDelay>0) AND (BarDelay[2]<Step2BarDelay))  {BarDelay[2]++;}  //set bar delay count
	    }
	  }
	  finalStep=0;
	  switch( NumStep )
	  {
	  case 1:
			finalStep=active[1]; 
			break;

	  case 2:
			finalStep=active[2];
			break;
			
	  case 3:
			finalStep=active[3];
			break;
	  }
	  
	  if (Step1[i]==1) //Step1 increment bar delay
	  {	
		if ((Step1BarDelay>0) AND (BarDelay[1]<Step1BarDelay))  {BarDelay[1]++;}  //set bar delay count
	  }
	  //las Step defined by "NumStep" sets when sequence completed
	  if (finalStep==1)
	  {
		res[i]=1;
		active=0; //clear active flags array
		BarDelay=0; //clear array used for bar delay checks
	  }
	}
	return res;
}

//Usage or call to Function is something like (the steps are for example):
//sequence with 2 steps
e1=Cross(MA(price,10),price); //step1
e1reset =0;
e2=Cross(MA(price,20),price) //step2
e3=0;
StepsCNT = 2; //steps can be 2 or 3 to have a real sequence
seqs1 = SequenceSteps(StepsCNT,e1,e1reset,0,e2,0,0,e3,0);
Buy = seqs1; //no real trading here just for demo of code

1 Like

I am not sure what you are trying to achieve in terms of performance, but since your code has only one loop, its performance isn't that bad. Array-wise the same can be achieved using statements like this:

// give 1 if step2 follows step1
seq1 = BarsSince( ExRem( Step1, Step1Reset ) ) >
       BarsSince( ExRem( Step2, Step2Reset ) ) ;
2 Likes

Thanks for response.

I tried your recommendation but it doesn't make unique sequences. Using BarsSince() reuses steps conditions from previous detected sequence. Each consecutive Step1 to Step3 must be unique within a sequence and not reused in subsequent sequences.

So I tried this code based on your Hints:
Code still gives me Sequences that use values from previous detected sequence.
Any Hints on making sure that sequences don't use previous Step1, Step2 or Step3 already used in previous sequences.

	//clean arrays no consecutive repeated signals
	Step1 = ExRem(Step1, NOT(Step1)); 
	Step2 = ExRem(Step2, NOT(Step2));
	Step3 = ExRem(Step3, NOT(Step3));
	//sequence reset if reset condition
	Step1=IIf(Step1reset,0,Step1);
	Step2=IIf(Step2reset,0,Step2);
	Step3=IIf(Step3reset,0,Step3);
    	
    SeqA = BarsSince(Step1) >= BarsSince(Step2) >= BarsSince(Step3);

    //trying next line of code: new sequence can't use previous sequence steps
    //Doesn't work - a sequence may use BarsSince(Step1) and reuse a Step1 from a previous detected sequence in array seqs1
    seqs1 = BarsSince(SeqA) > BarsSince(Step1) >= BarsSince(Step2) >= BarsSince(Step3);