Look for past Areas-candles AFL

Hi friends, I'm newbie on AFL code and I'm trying a backtest to search some past areas to trigger the buy or sell order as this example.

Sin-t%C3%ADtulo-1

My code problem is on the loop, because I modify mi "BUYCondEntrada7" signal for every candle on the array and not respect the buy order correctly. I try to exit the loop by "Break" instruction when "BUYCondEntrada7==1" but not runs ok.

Provably I've some concept errors on AFL system, I learn a lot the last days but not enought.

Thanks a lot for your support in advance!

//Condiciones de BUY en la Zona
BUYCondZona1 = C>O;
BUYCondZona2 = H - L <= StopPermitido;
BUYCondZona3 = H - C < C - O;
BUYCondZona4 = V > Vol_Min;
				
//Condiciones de BUY en la Entrada
BUYCondEntrada1 = L<=Zona_Alta_Alta;
BUYCondEntrada2 = L>=Zona_Alta_Baja;
BUYCondEntrada3 = V<Vol_Entrada;
BUYCondEntrada4 = tn>=InicioJornada AND tn<=FinJornada;
BUYCondEntrada5 = MA_21 > Ref(MA_21,21);
BUYCondEntrada6 = MA_21 > MA_80;
						
for(i=0; i<BarCount; i++)
{
	if (i>=150)
	{
		for(j=i-150; j<i-VelasMINZona; j++)
		{				
			BUYCondEntrada7 = BUYCondZona1[j] AND BUYCondZona2[j] AND BUYCondZona3[j] AND BUYCondZona4[j];
			
			if (BUYCondEntrada7==1)
			break;
		}
		if (BUYCondEntrada7==1)
		break;
	}
} 

//Disparo BUY
Buy = BUYCondEntrada1 AND BUYCondEntrada2 AND BUYCondEntrada3 AND BUYCondEntrada4 AND BUYCondEntrada5 AND BUYCondEntrada6 AND BUYCondEntrada7 ;

Cheers,
Jose Antonio

@Optimvs welcome to the Forum.

A quick suggestion: when you post some code like the above, you should post the ENTIRE formula so other users will be able to run it without guessing what are all the variables you are using.

Moreover, if possible, always try to name your variables in English. I can easily figure out the meaning since I'm Italian but may some other users will find it more difficult.

I hope someone else here will be able to help you anyway just looking at your post, but I'm sure that following the above guidelines will improve your chances to get some useful help.

1 Like

Thanks @beppe for your suggestions, you are right! I update my vars and edit the original post with full code.

Thanks a lot and sorry for the inconvenience.

Cheers,
Jose Antonio.

There are the full code in english.

SetTradeDelays(1,0,0,0);
Setpositionsize(1, spsShares);

//Vars

//Trading schedule
InitSchedule = 90000;
EndSchedule = 190000;
VolMinZone = 450;
VolMinEntry = 200;
MaxStopLoss = 25;
MA_21 = MA (C,21);
MA_80 = MA (C,80);
HHZone = H;
LHZone = IIf(C>=O,Close,Open);
Vol_OK = IIf(V>=VolMinZone,1,0);
dn=DateNum();
tn=TimeNum();
MINZoneCandles = 3;
BUYCondEntry7 = 0;

//BUY Zone Conditions
BUYCondZone1 = C>O;
BUYCondZone2 = H - L <= MaxStopLoss;
BUYCondZone3 = H - C < C - O;
BUYCondZone4 = V > VolMinZone;
				
//BUY Entry Conditions
BUYCondEntry1 = L<=HHZone;
BUYCondEntry2 = L>=LHZone;
BUYCondEntry3 = V<VolMinEntry;
BUYCondEntry4 = tn>=InitSchedule AND tn<=EndSchedule;
BUYCondEntry5 = MA_21 > Ref(MA_21,21);
BUYCondEntry6 = MA_21 > MA_80;
			
//StopLoss
StopLoss = L-2;
				
//SELL Conditions for BUY
SELLCond1 = V>1.5*VolMinZone;
SELLCond2 = tn>=EndSchedule;
SELLCond3 = MA_21<MA_80;

for(i=0; i<BarCount; i++)
{
	if (i>=150)
	{
		for(j=i-150; j<i-MINZoneCandles; j++)
		{							
			BUYCondEntry7 = BUYCondZone1[j] AND BUYCondZone2[j] AND BUYCondZone3[j] AND BUYCondZone4[j];
			
			if (BUYCondEntry7==1)
			break;
		}
		if (BUYCondEntry7==1)
		break;
	}
} 

//BUY Trigger
Buy = BUYCondEntry1 AND BUYCondEntry2 AND BUYCondEntry3 AND BUYCondEntry4 AND BUYCondEntry5 AND BUYCondEntry6 AND BUYCondEntry7 ;

//SELL Trigger
Sell = SELLCond1 OR SELLCond2 OR SELLCond3;
	
BuyPrice = O;
SellPrice = O;

ApplyStop(stopTypeNBar,stopModeBars,20,1); 	
ApplyStop(stopTypeLoss,stopModePoint,StopLoss,1);
ApplyStop(stopTypeProfit,stopModePoint,15,1);

//Plot
PlotShapes(IIf(Buy,shapeUpArrow,shapeNone),colorGreen,0,L, -30);
PlotShapes(IIf(Sell,shapeDownArrow,shapeNone),colorRed,0,H, 30);

BUYCondEntry7 is not an array.
Your loop will break when it is true or and as false, then you initialize Buy (which is an array) using it.

Thanks for your answer @awilson, I dont understand you,

My "BUYCondEntry7" is a static var, because when I make as array all "BUYCondEntry7[i]" changes while i increase.

I need when "BUYCondEntry7=1" in a zone trigger the Buy order if all others BUYCondEntry are true too.

Cheers,
Jose Antonio.

From your answer I believe you do not fully understand how AFL works, read the link below and use an excel to debug/understand your loop, you will understand me
https://www.amibroker.com/guide/h_understandafl.html

1 Like

Thanks @awilson, yes I wrote on my first post that I'm newbie on AFL code, I'll continue studying.

Cheers,
Jose Antonio.

@Optimvs, in addition to the suggestion by @awilson, this past thread will help to understand better how AmiBroker treats scalar and arrays and what happens when you assign a scalar to an array (Buy is an array).

Maybe in your loop you should use:

BUYCondEntry7[j] = .... 

or

if (BUYCondEntry7[j]) 
    ....

But probably it is better to use array operations as:

BUYCondEntry7 = BUYCondZone1 AND BUYCondZone2 AND BUYCondZone3 AND BUYCondZone4;

And then use some extra code/condition to apply it only when it is TRUE in your desired bars range/ areas (as said it is not clear to me why you are using a loop for this).

As a debugging / learning AFL tool I strongly suggest you to use some Exploration code.

As a minimum, add to your formula these lines:

Filter = 1;
AddColumn( BUYCondEntry7, "BUYCondEntry7", 1 );
AddColumn(  Buy, "Buy", 1 );

And execute the Analysis on a single ticker for some 300 recent bars.

As a beginner, I will probably use a more verbose exploration like this:

function nil( a )
{
    return ( IIf( a, a, Null ) );
}
Filter = 1;
AddColumn( C, "Close" );
AddColumn( O, "Open" );
AddColumn( H, "High" );
AddColumn( L, "Low" );
AddColumn( V, "Volume", 1 );
AddColumn( Nil( BUYCondZone1 ), "C>O", 1 );
AddColumn( Nil( BUYCondZone2 ), "H-L<=MaxSL", 1 );
AddColumn( Nil( BUYCondZone3 ), "H-C<C-O", 1 );
AddColumn( Nil( BUYCondZone4 ), "V>VMinZ", 1 );

//BUY Entry Conditions
AddColumn( Nil( BUYCondEntry1 ), "L<=HHZ", 1 );
AddColumn( Nil( BUYCondEntry2 ), "L>=LHZ", 1 );
AddColumn( Nil( BUYCondEntry3 ), "V<VolMinEn", 1 );
AddColumn( Nil( BUYCondEntry4 ), "tn>=In.AND tn<=End", 1 );
AddColumn( Nil( BUYCondEntry5 ), "MA_21>Ref(MA_21,21)", 1 );
AddColumn( Nil( BUYCondEntry6 ), "MA_21>MA_80", 1 );
AddColumn( Nil( BUYCondEntry7 ), "COND 7", 1 );
AddColumn( Nil( Buy ), "Buy", 1 );
AddColumn( Nil( Sell ), "Sell", 1 );
SetSortColumns( -2 );

(And if needed will also add some other used arrays like tn, MA_21, MA_80, etc.)

1 Like

Thanks a lot your explanation @beppe, I apreciate your contribution, I'm re-reading all this manual URLs and not found the key to solve my problem, I understand how works AFL flow and array vars funtionality, but I need go back in time to search particular condictions on last bars.

As exemple of the picture I need on candle[300] look back all BUYCondZones from candle 0 to 299 and save on BUYCondEntry7[300], so the only one way that i found is by loop for or double for.

If you know any better solution I appreciate so much.

Cheers,
Jose Antonio

The code below was not tested,

SetTradeDelays(1,0,0,0);
Setpositionsize(1, spsShares);

//Vars

//Trading schedule
InitSchedule = 90000;
EndSchedule = 190000;
VolMinZone = 450;
VolMinEntry = 200;
MaxStopLoss = 25;
MA_21 = MA (C,21);
MA_80 = MA (C,80);
HHZone = H;
LHZone = IIf(C>=O,Close,Open);
Vol_OK = IIf(V>=VolMinZone,1,0);
dn=DateNum();
tn=TimeNum();
MINZoneCandles = 3;
BUYCondEntry7 = 0;

//BUY Zone Conditions
BUYCondZone1 = C>O;
BUYCondZone2 = H - L <= MaxStopLoss;
BUYCondZone3 = H - C < C - O;
BUYCondZone4 = V > VolMinZone;
				
//BUY Entry Conditions
BUYCondEntry1 = L<=HHZone;
BUYCondEntry2 = L>=LHZone;
BUYCondEntry3 = V<VolMinEntry;
BUYCondEntry4 = tn>=InitSchedule AND tn<=EndSchedule;
BUYCondEntry5 = MA_21 > Ref(MA_21,21);
BUYCondEntry6 = MA_21 > MA_80;
			
//StopLoss
StopLoss = L-2;
				
//SELL Conditions for BUY
SELLCond1 = V>1.5*VolMinZone;
SELLCond2 = tn>=EndSchedule;
SELLCond3 = MA_21<MA_80;

/*
for(i=0; i<BarCount; i++)
{
	if (i>=150)
	{
		for(j=i-150; j<i-MINZoneCandles; j++)
		{							
			BUYCondEntry7 = BUYCondZone1[j] AND BUYCondZone2[j] AND BUYCondZone3[j] AND BUYCondZone4[j];
			
			if (BUYCondEntry7==1)
			break;
		}
		if (BUYCondEntry7==1)
		break;
	}
} 
*/
BUYCondEntry7 = BUYCondZone1 AND BUYCondZone2 AND BUYCondZone3 AND BUYCondZone4;
BUYCondEntry7 = Sum(BUYCondEntry7, 150-MINZoneCandles);
BUYCondEntry7 = Ref(BUYCondEntry7, -MINZoneCandles);
//BUY Trigger
Buy = BUYCondEntry1 AND BUYCondEntry2 AND BUYCondEntry3 AND BUYCondEntry4 AND BUYCondEntry5 AND BUYCondEntry6;
Buy = Buy AND BUYCondEntry7 > 0;

//SELL Trigger
Sell = SELLCond1 OR SELLCond2 OR SELLCond3;
	
BuyPrice = O;
SellPrice = O;

ApplyStop(stopTypeNBar,stopModeBars,20,1); 	
ApplyStop(stopTypeLoss,stopModePoint,StopLoss,1);
ApplyStop(stopTypeProfit,stopModePoint,15,1);

//Plot
PlotShapes(IIf(Buy,shapeUpArrow,shapeNone),colorGreen,0,L, -30);
PlotShapes(IIf(Sell,shapeDownArrow,shapeNone),colorRed,0,H, 30);

2 Likes

@Optimvs, maybe the proposed solution by @awilson is what you are looking for, but I think that you need to double check some of your conditions.

In particular, I find this one very dubious:

LHZone = IIf( C >= O, Close, Open );
BUYCondEntry2 = L >= LHZone; // Never Greater.... 

How frequently will it be True?

(Moreover, BUYCondEntry1, as presently coded, is ALWAYS True - so you can discard it).

As said, a detailed exploration is a great help when your code has a lot of conditions to verify.

1 Like

Thanks @awilson and @beppe for your answers, I'm study your your solution @awilson and its perfect.
I could not imagine this AFL code to solve a loop, I'm very impressed, its powerfull. Thanks a lot for share with me and open my mind to others solutions in my code.

@beppe when I use BUYCondEntry2 need compare L[i] >= LHZone[j]; I has an error here. Thanks for your contribution.

Cheers,
Jose Antonio

1 Like