Scan shows custom stops not working - perplexed

First, I have to say that some of you on this forum are brutal. So, I will tell you upfront that I have spent several days straight for 10 hours per day trying to learn where this is wrong. And, I have programming experience. So, please get off your high horse and try to help. Do I sound defensive? Yes, because of what I have read on this forum. I don't want my head chewed off. Especially when I'm frustrated with this issue and the scattershot approach to documentation. (I know I haven't gained any friends by saying this, but I'm as frustrated as you old-timers here are frustrated with people who don't research first.)

So, on with my issue:

  • This is not my system.
  • It's a Futures system marketed years ago. I'm using it to learn AmiBroker and AFL.
  • Volatility breakout system
  • Basically, get in on a stop and exit whenever the high of entry day is subsequently exceeded (Long)
  • I coded the Long side only
  • To code my custom stops I used the template found here: Back testing your trading ideas
  • I coded the equivalent of this code and was able to paint the bars to verify that the signals are correct. I had no issues with plotting.
  • Scan shows alternating buys and sells, but they occur on the same date and always on the close.
  • I investigated the reason for line above in all of the documentation and here as well, and it is still unclear to me.
  • I have done quite a bit of experimentation as well.
  • The code below is fully commented.

I'm sure that either I am doing something very stupid and I can't see it at the moment because I have "frustrated-coding-blindness" at the moment, or there is something simple that I have failed to understand about the product.

Here is the complete code that shows no issues when debugged and code verified:

PositionSize = 1;
SetBacktestMode( backtestRegular ); 
SetOption("InitialEquity",100000000000000000);
SetOption("AllowSameBarExit",True);
SetOption("ActivateStopsImmediately",True);
SetOption("FuturesMode",True);
SetOption("CommissionMode",2);
SetOption("CommissionAmount",0);
SetOption("EveryBarNullCheck",True);
SetOption("PriceBoundChecking", True);

c1 = Ref(C,-1);								// Yesterday's Close
th = Max(High,Ref(Close,-1));				// True High
tl = Min(Low,Ref(Close,-1));				// True Low
tr = th - tl;								// True Range
tr1 = Ref(tr,-1);							// Yesterday's True Range
df = MA(C,3);								// Directional Filter
df2 = Ref(df,-2);							// Directional Filter two days ago
tf = df2;									// Trade Filter (Filters out normal signal)
bb = Max(tf,C1 + tr1);						// Buy Band: Max of Normal Signal and TF
sb = Min(tf,(C1 - tr1));					// Short Band: Min of Normal Signal and TF

bcnd1 = c1 < df2;							// Condition 1: Yesterday's Close < DF 2 days ago
bcnd2 = H >= bb;								// Condition 3: High >= Buy Band (i.e., Market made it to Entry value)
Buy = bcnd1 && bcnd2;						// Buy when all conditions are true

r = H - L;									// Daily Range
rtop3 = H - r/3;							// Value beginning the top third of Range
rbot3 = r/3 + L;							// Value beginning the bottom third of Range

bxf1 = O >= rtop3;							// Raw: High occurs first, so Long Profit hit first.
bsf1 = O <= rbot3;							// Raw: Low occurs first, so Long Stop hit first.
brand = mtRandomA();						// Random numbers
bxf = bxf1 || (brand <= .6);				// High occurs first or 60% chance Long Profit hit first, when I can't tell. 
bsf = bsf1 || (brand <= .4);				// Low occurs first or 40% chance Long Stop hit first, when I can't tell.

BuyPrice = Max(O,bb);						// Execution Price is the Open if it is above the Buy Band, else Buy Band

// Prepopulate variables for loop

 lflat = True;								// Trading Long is flat, i.e., no Long trade
 lexit = Null;								// Long Exit value set to Null
 lstop = Null;								// Long Stop value set to Null

for( n = 0; n < BarCount; n++ ) 
 { 	
	  if( lflat && NOT Buy[ n ] )			// Long Market is flat and there is NO entry today
		Sell[ n ] = 0;
		continue;
	
	  if( lflat && Buy[ n ] )				// Long Market is flat and there IS an entry today
		Sell[ n ] = 0;
		lexit = H[ n ];
		lstop = L[ n ];
		lflat = False;
		Continue;
		
	// Market is in Long Trade - Process the Trade through Exit
	  
	  if( ( NOT lflat ) && ( O[ n ] >= lexit ) )   // Gap Open (gap in relation to Target)
		Sell[ n ] = 1;
		SellPrice[ n ] = o[ n ];
		lexit = Null;
		lflat = False;
		continue;
	
	  if( ( NOT lflat ) && ( H[ n ] >= lexit ) && bxf[ n ] )  // Target Hit Directly
		Sell[ n ] = 1;
		SellPrice[ n ] = lexit;
		lexit = Null;
		lflat = False;
		continue;
	
	  if( ( NOT lflat ) && ( L[ n ] <= lstop ) && bsf[ n ] )  // Stop Hit Directly
		Sell[ n ] = 1;
		SellPrice[ n ] = lstop;
		lexit = Null;
		lflat = False;
		continue;
	 
	  if( ( NOT lflat ) && ( h[ n ] >= lexit ) && bsf[ n ] )	// Target Hit Indirectly
		Sell[ n ] = 1;
		SellPrice[ n ] = lexit;
		lexit = Null;
		lflat = False;
		continue;
	
	  if( ( NOT lflat ) && ( L[ n ] <= lstop ) && bxf[ n ] )  // Stop Hit Indirectly
		{
		Sell[ n ] = 1;
		SellPrice[ n ] = lstop;
		lexit = Null;
		lflat = False;
		continue;
		}
	  else
		Sell[ n ] = 0;
		continue;
	
 } 

The various exit logic is listed in descending logic order, i.e., most restrictive to most broad, and ending with an else to cover no match on any particular iteration. At any match 'continue' exits the current iteration, so that the others are not evaluated.

If you have any questions about the code, I'll be glad to answer them. If you can help me without biting my head off, I give you many thanks in advance.

(btw the alignment of the code looks off from when I pasted it. I hope it looks right when I hit Create Topic)

Thanks!

4 Likes

Thank you for posting code and commenting it so people don't need to scratch their heads.

I am not exactly sure what the actual problem is? "Not working" is a bit imprecise. If you described what do you expect the code to do and what you are getting instead of expectation (possibly with some screenshot) it would be easier to help you.

I would start with adding some exploration code and _TRACE as explained here: How do I debug my formula?

1 Like

OK, I have run your code under the Debugger.

It become quite obvious what the problem is. The indenting is misleading and suggests that first continue is part of if() clause but it isn't. There are no braces after if()

    if( lflat && NOT Buy[ n ] )  // Long Market is flat and there is NO entry today
      Sell[ n ] = 0;
      continue; // this is NOT PART OF if() clause - it is executed always!

You should write:

   if( lflat && NOT Buy[ n ] )  // Long Market is flat and there is NO entry today
   {
      Sell[ n ] = 0;
      continue; // THIS continue is part of if
   }

Note that the same continue problems exist in later parts of the code.

To prevent such problems in the future I strongly advise using Edit->Prettify Selection in the AFL Editor. After prettifying the code it becomes quite obvious that continue wasn't part of if clause.

One should also note that AFL is similar to C/C++/Javascript and its structure is controlled by visible characters such as braces ({}), and NOT by invisible characters / indenting (like Python).

6 Likes

Indeed, sometimes this is a GREAT debugging tool.

I used it many times, especially when I got some errors that I was not immediately able to figure out.
With unexpected indenting of code, the reformatted formula showed things that escaped me observing my original code.

You should add it to the " How do I debug my formula? thread.

3 Likes

Good idea, added now.

3 Likes

Thank you so very much, Tomasz! That was the key I needed. I really appreciate it.

Also, thank you for the Prettify Selection suggestion. That had completely escaped my attention.

I'm good for now. I believe those insights will help carry me through to the end.

Many thanks!!!

I agree with you. And, I'm glad I'm not the only one that has gotten thrown off by the indentation. And, your suggestion for it to be applied to the debug thread will help others in the future.

Thanks for your input.

Tomasz,
You are quite right when you said: "Not working" is a bit imprecise.

Yes, that is my fault. When I said, "shows no issues when debugged and code verified" I meant simply, but imprecisely, that I clicked the Verify Syntax button and no error was returned. And, when I clicked the debug button it ran without any popup error. This was all imprecise language.

My problem was stated in the bulleted list above the code. I was getting buys / sells on the same day and always on the close. This was at odds with what I was expecting from my code.

I'm sorry that all of that was less than precise. But, many thanks for your perseverance on my behalf in running the code yourself. I really appreciate it.

Thanks.
Matt

1 Like

No problem @2mc. Your original request in 1..10 scale was strong 9. So you don't need to be sorry or anything like that. If all the others provided so well prepared requests we would be in a perfect world. It makes a whole world of difference when you see that somebody has done his homework. Also worth noting is that not everybody here (me included) are not native English speakers so sometimes we are not super skilled in reading/writing nuances.

Also your code was syntactically 100% correct that is why you did not get any errors.

But "logical" errors and program flow issues are way more difficult to see and can't be really detected by the parser.

Don't worry, the problem like yours is happening even to seasoned programmers. It is dead easy to place semicolon in wrong place. Example:

for( i  = 0; i < 100; i++ ); 
   printf( "%g\n", i ); // surprise: this gets executed only once

Well, it is so darn easy to overlook that for loop has EMPTY body (semicolon at the end of the for statement that actually ends the loop).

for( i  = 0; i < 100; i++ ); // this loop ENDS here (it is empty loop because of semicolon)

For reference proper code:

for( i  = 0; i < 100; i++ ) // NO semicolon here 
   printf( "%g\n", i ); // this is a body of for loop and gets run 100 times

That is why it is good to be verbose and make a habit of placing braces even if there is just one statement:

for( i  = 0; i < 100; i++ ) // NO semicolon here 
{
   printf( "%g\n", i ); // this is a body of for loop and gets run 100 times
}
7 Likes

Thanks, Tomasz. That was very kind of you to say. I appreciate it!

2 Likes

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