Nesting loops (I know there must be a better way.)

Hello All,

I am trying to implement a pattern match searching from the most recent period back 100 bars. The simplest form of the pattern has three parts. First we find A, then looking back from there B, then looking back again, C, then, if we find a match, we move on to the next stop. The idea is to have an exploration that scans a long list and spits out candidates matching the pattern. There is quite a bit more to this, but this example is the core idea and it is SLOW. Is there an faster (array?) method to accomplish this?

A = funcA();
B = funcB();
C = funcC();
for(i = BarCount - 100; i > 0; i--)
{
D = False;
if (A[i])
	for(j = i; j > 0; j--)
	{
	if (B[j])
		for(k = j; k > 0; k--)
		{
		if (C[k])
			D = True;
			break;
		}
	}
}

Filter = D;

Thanks in advance,

   John

Do A, B, and C all need to occur within the previous 100 bars? I see that your current code is looking for A in the previous 100 bars, but then B can occur anytime before A and C can occur anytime before B, all the way back to the start of your (loaded) price history. Is that what you want?

If all conditions need to occur within 100 previous bars, I think you could do something like this untested snippet:

bsA = BarsSince(A);
bsB = bsA + Ref(BarsSince(B), -bsA);
bsC = bsB + Ref(BarsSince(C), -bsB);

Filter = bsC < 100;

So D is a scalar and you just want to detect if pattern occurred anywhere in the past, so first C came, then B and then A.
Then I am thinking that simple

D = LastValue( A AND BarsSince( B ) > 0 AND BarsSince( C ) > BarsSince( B ) );

should give same output as loop.

If you don't want scalar but vector output, simply remove LastValue.

2 Likes

Thanks for the example. The signals don't need to occur in any given number of bars, but are usually best when they occur in less than 30 bars.

Tomasz,

I was thinking of using a scalar, but your vector solution is better as I can test for signals in the last n days rather than day of.

Thanks for a fine program. Still trying to wrap my mind around this style of programming. My impulse is to write loops and such as that was the way it was done when I learned.

Best regards,

 John
1 Like

Note that with the solution provided by @Tomasz, a new occurrence of event C will break the pattern matching. So if the order of events is:

  • C B A: D is True
  • C B C A: D is False

Not sure whether that's an issue for you or not.

It is an issue, but a high level one. In pattern matching there is always the demon of precision, make the match too tight and you get no results, too loose and you get sloppy results. The old saw goes that the market doesn't repeat, but it rhymes. I am a music buff. Years ago I spent some time on fuzzy string matching in Python for song, genre, and and album names. The approach that intrigued me the most was the Levenshtein distance, which I think of as edit distance or the number of small changes needed to morph one thing into another. Perhasp something like that is a good way to quantify the sort of pattern matching that traders need to identify candidates for further examination.

Best,

 John
2 Likes

Speaking about distances, for what it is worth, you can limit allowable distance between events C B A

For example if you want AB distance to be 1...100 bars and CB distance 1..150 bars you could use:

DistanceAB = BarsSince( B );
DistanceBC = BarsSince( C ) - BarsSince( B );

D = A AND 
      DistanceAB > 0 AND DistanceAB <= 100 AND 
      DistanceBC > 0 AND DistanceBC <= 150;
3 Likes