Tagging all the bars from 'up' until 'down' cross over condition

I have a simple EMA up and down cross over. I want to mark in a separate array, all the bars from the up until down cross over.

Below is the code I have written for this.

Wanted to know from the seniors in the forum, if there is a better way to do this using loops or otherwise.

/* EMA Cross Over Parameters */

ShortEMA_Period = Param("ShortEMA_Period", 8, 1, 100, 1);
LongEMA_Period = Param("LongEMA_Period", 20, 1, 100, 1);
Long_EMA = EMA(Close, LongEMA_Period);
Short_EMA = EMA(Close, ShortEMA_Period);
EMA_CO_Up = IIf(Cross(Short_EMA, Long_EMA), 1, Null);
EMA_CO_Down = IIf(Cross(Long_EMA, Short_EMA), 1, Null);
BI = BarIndex();
BI_CO_Up = ValueWhen(EMA_CO_Up, BI);
BI_CO_Down = ValueWhen(EMA_CO_Down, BI);


/* Loop to tag all bars from up until down cross over */

for(i = 0; i < BarCount; i++)
{
	if(EMA_CO_Down[i])
	{
		for(j = i - (BI_CO_Down[i] - BI_CO_Up[i]); j <= i; j++)
		{
			TagArray1[j] = 1;
		}
	}
}

Filter = 1;
AddColumn(BI, "BI");
AddColumn(EMA_CO_Up, "EMA CO Up");
AddColumn(EMA_CO_Down, "EMA CO Down");
//AddColumn(BI_CO_Up, "BI CO Up");
//AddColumn(BI_CO_Down, "BI CO Down");
AddColumn(TagArray1, "Tag Array 1");

Required Output Reference Image as below:

Ref_Image

Instead of loop you just need single line

TagArray1 = Flip(EMA_CO_Up, EMA_CO_Down) OR EMA_CO_Down*ValueWhen(EMA_CO_Up,1);
3 Likes

Though this would take a little while for me to come in terms with and understand, this is just brilliant fxshrat, thank you so much!

Flip function alone does the job

TagArray1 = Flip(EMA_CO_Up, EMA_CO_Down);

See the manual:

ValueWhen serves no purpose here and is redundant.

Also note that the value that you are really calculating with all that convoluted code is simple > (greater than), so you could achive the same as simply as:

TagArray1 = Short_EMA > Long_EMA; // that what it really is
1 Like

Its purpose is to avoid marking EMA_CO_Down at start of array if it returns true before EMA_CO_Up.

No, please take a look at first post. He wanted to include bar at cross down.

But that still does not mark true at cross down.

23

So AFAICS according to requirement of 1st post it is not full solution (yet).

2 Likes

I tried the code Dr. Tomasz, I suppose the valuewhen bit what fxshrat has used is because when using flip, the last bar where EMA_CO_Down is true does not get tagged.

And on the 2nd point, I understand completely what you have conveyed, will get better with this, thank you.

ValueWhen is frequently overused in many formulas and tends to make them looking more complicated that they really are.

To include that "down" point, you don't need ValueWhen
Just use simple OR with variable:

TagArray1 = Flip(EMA_CO_Up, EMA_CO_Down) OR EMA_CO_Down;

Or you could use Ref()

// reset later via Ref
TagArray1 =  Flip(EMA_CO_Up, Ref( EMA_CO_Down, -1 ) ); 

Or you can use Hold for one bar more:

TagArray1 = Hold( Flip(EMA_CO_Up, EMA_CO_Down), 2 );

Value when is NOT needed..

The same with greater operator code, you can achieve what you want with:

TagArray1 = Short_EMA > Long_EMA OR EMA_CO_Down;

or version with Hold:

TagArray1 = Hold( Short_EMA > Long_EMA, 2 );

Also note that I would be very careful with including this "down" point because at that bar, the long time average is ALREADY below short time and keeping positions longer usually results in trading loses (keep in mind that averages ALWAYS introduce delays, so the signals are DELAYED already - what you are trying to do is essentially increasing this delay by one extra bar and it is really bad idea because delays in response always result in bad system performance ).

8 Likes

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.