User mistake, sigScaleIn without existing trade just opens new trade, was: Debugger showing different results from Backtester

Good day, sirs.

Well, im trying to implement a ScaleIn system using a for loop configuration. The rules are simple:

1 - When buy/short (1 share only!), if price achieve the ScaleIn Price, enter a second share.

2 - If it reaches the stop loss or reaches the original EntryPrice, Exit the whole position.

In the debugger, the results are exactly as i want them to be:

Image%2023

But in backtest, the same "entries" show results completely different:

Image%2025

What am I doing wrong?

Here is my code:

Buy = BuyConditions;
Short = ShortConditions;
BuyPrice = EntryPriceBuy;
ShortPrice = EntryPriceShort;

trailstop = 0;
Comprado = 0 ; //in english it means "InLongPosition"
Vendido = 0 ; //in english it means "InShortPosition"
precoentrada= 0 ;  //in english it means "EntryPrice"
precosaida = 0; //in english it means "ExitPrice". The StopLoss price
highsincebuy = -100000 ;
lowsinceshort = 100000 ; 
alvo = 0; //in english it means "TakeProfit"
ScalePrice = 0;
Combo = 0; //I use this so if ScaleIn occurs at the Entry bar, I can enter 2 shares instead of 1. 

estagio = 0 ;  //If price achieved "Activationfloor", Stage = 1, if achieved "ScaleIn", Stage = 2.

for( i = 53; i < BarCount; i++ ) 
{ 
    Combo[i] = 0;
    if( precoentrada == 0 AND Buy[ i ] ) 
    { 
	   Comprado = 1 ;
       precoentrada = BuyPrice[ i ]; //vai dar o preço de compra... Entryprice
       ScalePrice = precoentrada - STP_Sc;
       precosaida = precoentrada - STP_Sc - STP_L;
       alvo = precoentrada + STP_G;
       
       
       if(Low[ i ] <= ScalePrice)
            {
                Buy[ i ] = sigScaleIn;
                buyPrice[i] = (floor(((precoentrada - ScalePrice)/2)/TickSize)*TickSize)+ScalePrice;
                estagio = 2; 
                Combo[i] = 1;
                
                if( Low[i] <= precosaida)
                {
					
					Sell[ i ] = 21; // mark appropriate exit code 
					SellPrice[i] = precosaida;
					estagio = 0; 
					precoentrada = 0; // reset price 
					precosaida = 0;
					highsincebuy = -10000; 
					comprado = 0;
					alvo = 0;
					ScalePrice = 0;
                
                }
                
               else if( close[i] >= precoentrada)
                {
					 
					Sell[ i ] = 31; // mark appropriate exit code 
					SellPrice[i] = precoentrada;
					estagio = 0; 
					precoentrada = 0; // reset price 
					precosaida = 0;
					highsincebuy = -10000; 
					comprado = 0;
					alvo = 0;
					ScalePrice = 0;
                
                }
                
            }
            
        else if( Close[ i ] >= (precoentrada + bk*TickSize) ) 
            { 
               // first profit target hit - scale-out 
               //highsincebuy = Max( High[ i ], highsincebuy );
               estagio = 1; 
               //trailstop = (highsincebuy - (precoentrada + bk*TickSize)) + precoentrada;
                
                if(Close[i] >= alvo)
                { 
					 
					Sell[ i ] = 51; // mark appropriate exit code 
					SellPrice[i] = alvo;
					comprado = 0;
					estagio = 0; 
					precoentrada = 0; // reset price 
					precosaida = 0;
					highsincebuy = -10000; 
					comprado = 0;
					alvo = 0;
					trailstop = 0;
					ScalePrice=0;
                }     
            } 
    } 
    
    else if( precoentrada == 0 AND Short[ i ])
    {
       Vendido = 1 ;
       precoentrada = ShortPrice[ i ];
       ScalePrice = precoentrada + STP_Sc;
       precosaida = precoentrada + STP_Sc + STP_L;
       alvo = precoentrada - STP_G;
       
       if( high[ i ] >= ScalePrice)
            {
                short[ i ] = sigScaleIn;
                shortPrice[i] = ScalePrice - (ceil(((ScalePrice - precoentrada)/2)/TickSize)*TickSize);
                estagio = 2; 
                Combo[i] = 1;
                  
                if( High[i] >= precosaida)
                {
					 
					cover[ i ] = 21; // mark appropriate exit code 
					CoverPrice[i] = precosaida;
					estagio = 0; 
					precoentrada = 0; // reset price 
					precosaida = 0;
					lowsinceshort = 10000; 
					vendido = 0;
					alvo = 0;
					ScalePrice=0;
                  
                }
                  
                else if(Close[i] <= precoentrada)
                {
					 
					cover[ i ] = 31; // mark appropriate exit code 
					CoverPrice[i] = precoentrada;
					estagio = 0; 
					precoentrada = 0; // reset price 
					precosaida = 0;
					lowsinceshort = 10000; 
					vendido = 0;
					alvo = 0;
					ScalePrice=0;
                  
                  
                }
            }
            
       else if( Close[ i ] <= (precoentrada - bk*TickSize) ) 
            { 
                 //lowsinceshort = min( low[ i ], lowsinceshort );
                 // first profit target hit - scale-out 
                 estagio = 1; 
                 //trailstop = precoentrada - ((precoentrada - bk*TickSize) - lowsinceshort); 
                    
                 if( Close[i] <= alvo) 
					{ 
						 
						cover[ i ] = 51; // mark appropriate exit code 
						CoverPrice[i] = alvo;
						vendido = 0;
						estagio = 0; 
						precoentrada = 0; // reset price 
						precosaida = 0;
						lowsinceshort = 10000;   
						alvo=0;
						trailstop=0;
					} 
            } 
    }

    else if( precoentrada > 0 )  //se já estiver comprado...
    { 
    
      if( Comprado == 1 )
        {
          highsincebuy = Max( High[ i ], highsincebuy ); 
          
          if( estagio == 0 AND
            Low[ i ] <= ScalePrice)
            {
                Buy[ i ] = sigScaleIn;
                buyPrice[i] = ScalePrice;
                estagio = 2; 
                
                if( Low[i] <= precosaida)
                {
					
					Sell[ i ] = 22; // mark appropriate exit code 
					SellPrice[i] = precosaida;
					estagio = 0; 
					precoentrada = 0; // reset price 
					precosaida = 0;
					highsincebuy = -10000; 
					comprado = 0;
					alvo = 0;
					ScalePrice = 0;
                
                }
                
               else if( close[i] >= precoentrada)
                {
					 
					Sell[ i ] = 32; // mark appropriate exit code 
					SellPrice[i] = precoentrada;
					estagio = 0; 
					precoentrada = 0; // reset price 
					precosaida = 0;
					highsincebuy = -10000; 
					comprado = 0;
					alvo = 0;
					ScalePrice = 0;
                
                }
                
            }

          else if( estagio == 0 AND 
             High[ i ] >= (precoentrada + bk*TickSize) ) 
            { 
               // first profit target hit - scale-out 
               estagio = 1; 
               trailstop = (highsincebuy - (precoentrada + bk*TickSize)) + precoentrada;
               
               if( Close[i] <= trailstop ) 
				{ 
					
					Sell[ i ] = 42; // mark appropriate exit code 
					SellPrice[i] = trailstop;
					comprado = 0;
					estagio = 0; 
					precoentrada = 0; // reset price 
					precosaida = 0;
					highsincebuy = -10000; 
					comprado = 0;
					alvo=0;
					trailstop = 0;
					ScalePrice=0;
                }     
                
                else if(High[i] >= alvo)
                { 
					 
					Sell[ i ] = 52; // mark appropriate exit code 
					SellPrice[i] = alvo;
					comprado = 0;
					estagio = 0; 
					precoentrada = 0; // reset price 
					precosaida = 0;
					highsincebuy = -10000; 
					comprado = 0;
					alvo = 0;
					trailstop = 0;
					ScalePrice=0;
                }     
            } 

          

          else if( estagio == 1)
            { 
            //trailstop = (highsincebuy - (precoentrada + bk*TickSize)) + precoentrada;
            
            if( Low[i] <= trailstop) 
               { 
                
               Sell[ i ] = 43; // mark appropriate exit code 
               SellPrice[i] = trailstop;
               comprado = 0;
               estagio = 0; 
               precoentrada = 0; // reset price 
               precosaida = 0;
               highsincebuy = -10000; 
               comprado = 0;
               alvo=0;
               trailstop = 0;
               ScalePrice=0;
               } 
             
          else if( High[i] >= alvo)
               { 
				 
				Sell[ i ] = 53; // mark appropriate exit code 
				SellPrice[i] = alvo;
				comprado = 0;
				estagio = 0; 
				precoentrada = 0; // reset price 
				precosaida = 0;
				highsincebuy = -10000; 
				comprado = 0;
				alvo = 0;
				trailstop=0;
				ScalePrice=0;
               } 
               
               trailstop = (highsincebuy - (precoentrada + bk*TickSize)) + precoentrada;  
            } 
            
          else if( estagio == 2)
            { 
                        
            if( Low[i] <= precosaida) 
               { 
                
               Sell[ i ] = 23; // mark appropriate exit code 
               SellPrice[i] = precosaida;
               comprado = 0;
               estagio = 0; 
               precoentrada = 0; // reset price 
               precosaida = 0;
               highsincebuy = -10000; 
               comprado = 0;
               alvo=0;
               trailstop = 0;
               ScalePrice = 0;
               } 
             
          else if( High[i] >= precoentrada)
               { 
				 
				Sell[ i ] = 33; // mark appropriate exit code 
				SellPrice[i] = precoentrada;
				comprado = 0;
				estagio = 0; 
				precoentrada = 0; // reset price 
				precosaida = 0;
				highsincebuy = -10000; 
				comprado = 0;
				alvo = 0;
				trailstop=0;
				ScalePrice=0;
               }   
            }     
        } 
    
    
    
    
    
    
       //vendido!
    
    
    
    
      else if( Vendido == 1 )
        {
            lowsinceshort = min( low[ i ], lowsinceshort ); 
          
            if( estagio == 0 AND
               high[ i ] >= ScalePrice)
            {
                  short[ i ] = sigScaleIn;
                  shortPrice[i] = ScalePrice;
                  estagio = 2; 
                  
                  if( High[i] >= precosaida)
                {
					 
					cover[ i ] = 22; // mark appropriate exit code 
					CoverPrice[i] = precosaida;
					estagio = 0; 
					precoentrada = 0; // reset price 
					precosaida = 0;
					lowsinceshort = 10000; 
					vendido = 0;
					alvo = 0;
					ScalePrice=0;
                  
                }
                  
                else if(Close[i] <= precoentrada)
                {
					
					cover[ i ] = 32; // mark appropriate exit code 
					CoverPrice[i] = precoentrada;
					estagio = 0; 
					precoentrada = 0; // reset price 
					precosaida = 0;
					lowsinceshort = 10000; 
					vendido = 0;
					alvo = 0;
					ScalePrice=0;
                  
                  
                }
            }

            else if( estagio == 0 AND 
               low[ i ] <= (precoentrada - bk*TickSize) ) 
                { 
                 // first profit target hit - scale-out 
                 estagio = 1; 
                 trailstop = precoentrada - ((precoentrada - bk*TickSize) - lowsinceshort); 
                 
                 
                 if( Close[i] >= trailstop) 
                    
                     
					{ 
						 
						cover[ i ] = 42; // mark appropriate exit code 
						CoverPrice[i] = trailstop;
						vendido = 0;
						estagio = 0; 
						precoentrada = 0; // reset price 
						precosaida = 0;
						lowsinceshort = 10000;   
						alvo=0;
						trailstop=0;
					} 
					
				 else if( Low[i] <= alvo) 
					{ 
						
						cover[ i ] = 52; // mark appropriate exit code 
						CoverPrice[i] = alvo;
						vendido = 0;
						estagio = 0; 
						precoentrada = 0; // reset price 
						precosaida = 0;
						lowsinceshort = 10000;   
						alvo=0;
						trailstop=0;
					} 
                } 

            

            else if( estagio == 1)
            { 
              //trailstop = precoentrada - ((precoentrada - bk*TickSize) - lowsinceshort);
            
              if( High[i] >= trailstop) 
                { 
                 
                 cover[ i ] = 43; // mark appropriate exit code 
                 CoverPrice[i] = trailstop;
                 vendido = 0;
                 estagio = 0; 
                 precoentrada = 0; // reset price 
                 precosaida = 0;
                 lowsinceshort = 10000; 
                 alvo = 0;   
                 trailstop=0;            
                } 
                
            else if( low[i] <= alvo) 
				{ 
				
				cover[ i ] = 53; // mark appropriate exit code 
				CoverPrice[i] = alvo;
				vendido = 0;
				estagio = 0; 
				precoentrada = 0; // reset price 
				precosaida = 0;
				lowsinceshort = 10000;   
				alvo=0;
				trailstop=0;
				}
				
				trailstop = precoentrada - ((precoentrada - bk*TickSize) - lowsinceshort);     
            }
            
            else if( estagio == 2)
            { 
                
              if( High[i] >= precosaida) 
                { 
                 
                 cover[ i ] = 23; // mark appropriate exit code 
                 CoverPrice[i] = precosaida;
                 vendido = 0;
                 estagio = 0; 
                 precoentrada = 0; // reset price 
                 precosaida = 0;
                 lowsinceshort = 10000; 
                 alvo = 0;   
                 trailstop=0; 
                 ScalePrice=0;           
                } 
                
            else if( low[i] <= precoentrada) 
				{ 
				short[ i ] = 0; 
				cover[ i ] = 33; // mark appropriate exit code 
				CoverPrice[i] = precoentrada;
				vendido = 0;
				estagio = 0; 
				precoentrada = 0; // reset price 
				precosaida = 0;
				lowsinceshort = 10000;   
				alvo=0;
				trailstop=0;
				ScalePrice=0;
				}     
            }
        }
    
    
    
    
    }
} 



EntryPosSize1 = 1; // Size for first entry
EntryPosSize2 = 1; // Size for second entry
PosSize = (IsTrue(Buy OR Short) * EntryPosSize1) + (IsTrue(combo) * EntryPosSize2);
             
SetPositionSize(PosSize, spsShares);

For explicit Signals, using flags you might need to re-construct the framework of the for-loop to something like this:

_Buy = /*Your Buy Rule>*/;
_Short = /*Your Short Rule>*/;

//Array Initialization
Buy = Sell = Short = Cover = Null;
LongFlag = ShortFlag = 0; //Simple Flag arrays to identify whether in a Long or Short position

//Using Loop to generate signals
for( i = 0; i < BarCount; i++ ) {

	 //Long Positions
	 if( _Buy[ i ] AND LongFlag == 0 ) {
		 Buy[ i ] = 1;
		 LongFlag = 1;  //To record that we are in Long position
	 }
	 if( _Short[ i ] AND LongFlag == 1 ) {
		 Sell[ i ] = 1;  //Selling-off the Long position
		 LongFlag = 0;   //Reseting LongFlag back to False, to denote that we are no longer in "Long" position
	 }

	 //Short Positions
	 if( _Short[ i ] AND ShortFlag == 0 ) {
		 Short[ i ] = 1;
		 ShortFlag = 1;	  //To record that we are in Short position
	 } 
	 if( _Buy[ i ] AND ShortFlag == 1 ) {
		 Cover[ i ] = 1;  //Covering the Short position
		 ShortFlag = 0;   //Reseting ShortFlag back to False, to denote that we are no longer in "Short" position
	 }
}

Now you extend the above to insert rules for when and how to Scale-In/Out rules. Put the below code in your AFL Editor, play with it and accordingly modify it to suit your needs:

//https://forum.amibroker.com/t/debugger-showing-different-results-from-backtester/12873?u=cougar
//A Simple Demo Intraday Strategy
_SECTION_BEGIN( "Trade Execution Prices" );
	 SetChartBkColor( colorBlack );
	 SetChartOptions( 0, chartShowDates );
	 
	 Per = Param( "Swing Periods", 15, 3, 144, 1 );
	 HigherHighs = HHV( H, Per );
	 LowerLows = LLV( L, Per );
	 _Buy = Cross( H, Ref( HigherHighs, -1 ) );
	 _Short = Cross( Ref( LowerLows, -1 ), L );

	 tn = TimeNum();
	 //No new postion to take after this time and close the open ones
	 //Not necessarily one has to implement, however, good practice for building daytrading strategies
	 //If your timeframe is Higher and more prone to keep positions overnight, then,
	 //You can avoid using this
	 DaysPostionCloseTime = 150000;

	 MultATR = Param( "ATR Multiplier", 2, 1, 4, 0.5 );
	 PerATR = Param( "ATR Period", 14, 3, 89, 1 );
	 _ATR = ATR( PerATR );	 
	 
	 //Array Initialization
	 Buy = Sell = Short = Cover = TSL = Null;
	 LongFlag = ShortFlag = 0; //Simple flags
	 
	 //Using Loop to generate signals
	 for( i = 0; i < BarCount; i++ ) {
		 //Long Positions
		 if( _Buy[ i ] AND LongFlag == 0 AND tn[ i ] < DaysPostionCloseTime ) {
			 Buy[ i ] = 1;
			 LongFlag = 1; //To record that we are in Long position
			 BuyPrice[ i ] = HigherHighs[ i ];
		 }		 
		 if( LongFlag ) {
			 //This is "When" to Scale-In or Scale-Out
			 //Set your rules on "how" to Scale-In or Out while in Long position
			 
			 //Traling Stop Loss
			 if( TSL[ i - 1 ] > H[ i ] - _ATR[ i ] * MultATR )
				 TSL[ i ] = TSL[ i - 1 ];
			 else
				 TSL[ i ] = H[ i ] - _ATR[ i ] * MultATR;
		 }
		 
		 if( ( _Short[ i ] OR L[ i ] < TSL[ i - 1 ] OR tn[ i ] >= DaysPostionCloseTime ) AND LongFlag == 1 ) {
			 Sell[ i ] = 1; //Selling-off the Long position
			 LongFlag = 0;  //Reseting LongFlag back to False, to denote that we are no longer in "Long" position
			 
			 //Setting different Sell-exit scenarios
			 if( _Short[ i ] )
				 SellPrice[ i ] = LowerLows[ i ]; //Your exit based on your pre-defined Target
			 else if( L[ i ] < TSL[ i - 1 ] )
				 SellPrice[ i ] = TSL[ i - 1 ];
			 else if( tn[ i ] >= DaysPostionCloseTime )
				 SellPrice[ i ] = O[ i ];
		 }
		 
		 if( Buy[ i ] ) PlotText( "Buy @" + NumToStr( BuyPrice[ i ], 1.2 ), i, L[ i ] - _ATR[ i ], colorBrightGreen, colorBlack );
		 if( Sell[ i ] ) PlotText( "Sell @" + NumToStr( SellPrice[ i ], 1.2 ), i, H[ i ] + _ATR[ i ], colorBrown, colorBlack );
		 
		 //Short Positions
		 if( _Short[ i ] AND ShortFlag == 0 AND tn[ i ] < DaysPostionCloseTime ) {
			 Short[ i ] = 1;
			 ShortFlag = 1;	 //To record that we are in Short position
			 ShortPrice[ i ] = LowerLows[ i ];
		 }
		 if( ShortFlag ) {
			 //This is "When" to Scale-In or Scale-Out
			 //Set your rules on "how" to Scale-In or Out while in Short position
			 
			 //Traling Stop Loss
			 if( TSL[ i - 1 ] < L[ i ] + _ATR[ i ] * MultATR )
				 TSL[ i ] = TSL[ i - 1 ];
			 else
				 TSL[ i ] = L[ i ] + _ATR[ i ] * MultATR;
		 }
		 
		 if( ( _Buy[ i ] OR H[ i ] > TSL[ i - 1 ] OR tn[ i ] >= DaysPostionCloseTime ) AND ShortFlag == 1 ) {
			 Cover[ i ] = 1; //Covering the Short position
			 ShortFlag = 0;  //Reseting ShortFlag back to False, to denote that we are no longer in "Short" position
			 
			 //Setting different Cover-exit scenarios
			 if( Cover[ i ] )
				 CoverPrice[ i ] = HigherHighs[ i ]; //Your exit based on your pre-defined Target
			 else if( H[ i ] > TSL[ i - 1 ] )
				 CoverPrice[ i ] = TSL[ i - 1 ];
			 else if( tn[ i ] >= DaysPostionCloseTime )
				 CoverPrice[ i ] = O[ i ];
		 }
		 
		 if( Short[ i ] ) PlotText( "Short @" + NumToStr( ShortPrice[ i ], 1.2 ), i, H[ i ] + _ATR[ i ], colorRed, colorBlack );
		 if( Cover[ i ] ) PlotText( "Cover @" + NumToStr( CoverPrice[ i ], 1.2 ), i, L[ i ] - _ATR[ i ], colorDarkGreen, colorBlack );
	 }
	 
	 //Plotting
	 Plot( C, "Price", colorDefault, styleBar | styleThick );
	 Plot( HigherHighs, "Highs", colorDarkGreen, styleDashed | styleNoRescale | styleNoLabel );
	 Plot( LowerLows, "Lows", colorBrown, styleDashed | styleNoRescale | styleNoLabel );
	 
	 PlotShapes( IIf( Buy, shapeUpArrow, shapeNone ), colorBrightGreen, 0, L - _ATR ); //Long Entry
	 PlotShapes( IIf( Sell, shapeSmallDownTriangle, shapeNone ), colorBrown, 0, H + _ATR, -20 ); //Long Exit
	 
	 PlotShapes( IIf( Short, shapeDownArrow, shapeNone ), colorRed, 0, H + _ATR, -20 ); //Short Entry
	 PlotShapes( IIf( Cover, shapeSmallUpTriangle, shapeNone ), colorDarkGreen, 0, L - _ATR ); //Short Exit
	 
	 Plot( TSL, "TSL", colorPink, styleThick | styleNoRescale ); //Trailing Stop-Loss
_SECTION_END();
3 Likes

Hello again!

So, I did as you told and rewrote my code so it would looks more like yours. But the same problem seems to occur.

Debugger:

02

Backtest:

01

And My new code:


SetBarsRequired( sbrAll, sbrAll );

/* Brazilian dollar ticksize */

TickSize = 0.5;
TF = Optimize("TempoMenor",1,1,1,5);
TrailActivator = Optimize("TrailDistance",8 ,2 ,8, 2); //4 a 12
Gain=Optimize("Gmult",10,2,20,2); // 4 a 20
Loss=Optimize("Lmult",2,2,4,2); //2 a 12
Trail = Optimize("TMult",2,4,8,2);
STP_G = Gain*TickSize; //StopGain Size
STP_L = Loss*TickSize; //StopLoss Size
STP_Sc = Loss*TickSize;
STP_Trail = Trail*TickSize;
TrailDistance = TrailActivator*TickSize;

SetTradeDelays(0,0,0,0);
SetOption( "ReverseSignalForcesExit", 0 );
SetOption("EveryBarNullCheck",1); 
SetOption("PriceBoundChecking",True);
SetOption("FuturesMode",1);
SetOption("MaxOpenPositions", 1);
SetOption("AllowSameBarExit", True ); 

tn = TimeNum();
exitcond = tn >= 171000;


Buy=Short=Sell=Cover=Null;

_Buy = conditions...
_Short = conditions...

InLong = 0;
InShort = 0;
FirstBar = 0;
Stage = 0;


for(i = 53; i < BarCount; i++)

{


if (_Buy[i] AND InLong == 0)
	{
	Buy[i] = 1;
	BuyPrice[i] = EntryPriceC[i];
	EntryPrice = BuyPrice[i];
	ScalePrice = EntryPrice - STP_Sc;
	LossPrice = ScalePrice - STP_L;
	FloorActPrice = EntryPrice + TrailDistance;
	ProfitPrice = EntryPrice + STP_G;
	InLong = 1;
	FirstBar = 1;
	HighestPrice = 0;
	}
	
if (InLong AND FirstBar == 1)
	{
	if (Low[i] <= ScalePrice AND Stage == 0)
		{
		Buy[i] = sigScaleIn;
		BuyPrice[i] = ScalePrice;
		Stage = 2;
		}
		
	if (Close[i] >= FloorActPrice AND Stage == 0)
		{
		TrailPrice = Close[i] - STP_Trail; 
		Stage = 1;
		}
		
	
	}
	
if (InLong AND FirstBar == 0)
	{
	if (Low[i] <= ScalePrice AND Stage == 0)
		{
		Buy[i] = sigScaleIn;
		BuyPrice[i] = ScalePrice;
		Stage = 2;
		}
		
	if (High[i] >= FloorActPrice AND Stage == 0)
		{
		HighestPrice = Max(High[i],HighestPrice);
		TrailPrice = HighestPrice - STP_Trail; 
		Stage = 1;
		}	
	}

if ( (FirstBar == 1 AND Stage == 2 AND Low[i] <= LossPrice) OR 
	 (FirstBar == 1 AND Stage == 2 AND Close[i] >= EntryPrice AND NOT Low[i] <= LossPrice) OR
	 (FirstBar == 1 AND Stage == 1 AND Close[i] >= ProfitPrice AND NOT Low[i] <= LossPrice) OR
	 (FirstBar == 0 AND Stage == 2 AND Low[i] <= LossPrice) OR
	 (FirstBar == 0 AND Stage == 2 AND High[i] >= EntryPrice AND NOT Low[i] <= LossPrice) OR
	 (FirstBar == 0 AND Stage == 1 AND Low[i] <= TrailPrice AND NOT Low[i] <= LossPrice) OR
	 (FirstBar == 0 AND Stage == 1 AND High[i] >= ProfitPrice AND NOT Low[i] <= TrailPrice) OR
	 (exitcond[i]) )
	{
	Sell[i] = 1;
	InLong = 0;
	
	if (Stage == 2 AND Low[i] <= LossPrice)
	SellPrice[i] = LossPrice;
	
	else if ( (FirstBar == 1 AND Stage == 2 AND Close[i] >= EntryPrice AND NOT Low[i] <= LossPrice) OR (FirstBar == 0 AND Stage == 2 AND High[i] >= EntryPrice AND NOT Low[i] <= LossPrice) )
	SellPrice[i] = EntryPrice;
	
	else if (FirstBar == 0 AND Stage == 1 AND Low[i] <= TrailPrice AND NOT Low[i] <= LossPrice) 
	SellPrice[i] = TrailPrice;
	
	else if ( (FirstBar == 1 AND Stage == 1 AND Close[i] >= ProfitPrice AND NOT Low[i] <= LossPrice) OR (FirstBar == 0 AND Stage == 1 AND High[i] >= ProfitPrice AND NOT Low[i] <= TrailPrice) )
	SellPrice[i] = ProfitPrice;
	
	else if (exitcond[i])
	SellPrice[i] = Close[i];
	
	Stage = 0;
	}




//Short Instructions



if (_Short[i] AND InShort == 0)
	{
	Short[i] = 1;
	ShortPrice[i] = EntryPriceV[i];
	EntryPrice = ShortPrice[i];
	ScalePrice = EntryPrice + STP_Sc;
	LossPrice = ScalePrice + STP_L;
	FloorActPrice = EntryPrice - TrailDistance;
	ProfitPrice = EntryPrice - STP_G;
	InShort = 1;
	FirstBar = 1;
	LowestPrice = 100000;
	}
	
if (InShort AND FirstBar == 1)
	{
	if (High[i] >= ScalePrice AND Stage == 0)
		{
		Short[i] = sigScaleIn;
		ShortPrice[i] = ScalePrice;
		Stage = 2;
		}
		
	if (Close[i] <= FloorActPrice AND Stage == 0)
		{
		TrailPrice = Close[i] + STP_Trail; 
		Stage = 1;
		}
		
	
	}
	
if (InShort AND FirstBar == 0)
	{
	if (High[i] >= ScalePrice AND Stage == 0)
		{
		Short[i] = sigScaleIn;
		ShortPrice[i] = ScalePrice;
		Stage = 2;
		}
		
	if (Low[i] <= FloorActPrice AND Stage == 0)
		{
		LowestPrice = Min(Low[i],LowestPrice);
		TrailPrice = LowestPrice + STP_Trail; 
		Stage = 1;
		}	
	}

if ( (FirstBar == 1 AND Stage == 2 AND High[i] >= LossPrice) OR 
	 (FirstBar == 1 AND Stage == 2 AND Close[i] <= EntryPrice AND NOT High[i] >= LossPrice) OR
	 (FirstBar == 1 AND Stage == 1 AND Close[i] <= ProfitPrice AND NOT High[i] >= LossPrice) OR
	 (FirstBar == 0 AND Stage == 2 AND High[i] >= LossPrice) OR
	 (FirstBar == 0 AND Stage == 2 AND Low[i] <= EntryPrice AND NOT High[i] >= LossPrice) OR
	 (FirstBar == 0 AND Stage == 1 AND High[i] >= TrailPrice AND NOT High[i] >= LossPrice) OR
	 (FirstBar == 0 AND Stage == 1 AND Low[i] <= ProfitPrice AND NOT High[i] >= TrailPrice) OR
	 (ExitCond[i]) )
	{
	Cover[i] = 1;
	InShort = 0;
	
	if (Stage == 2 AND High[i] >= LossPrice)
	CoverPrice[i] = LossPrice;
	
	else if ( (FirstBar == 1 AND Stage == 2 AND Close[i] <= EntryPrice AND NOT High[i] >= LossPrice) OR (FirstBar == 0 AND Stage == 2 AND Low[i] <= EntryPrice AND NOT High[i] >= LossPrice) )
	CoverPrice[i] = EntryPrice;
	
	else if (FirstBar == 0 AND Stage == 1 AND High[i] >= TrailPrice AND NOT High[i] >= LossPrice) 
	CoverPrice[i] = TrailPrice;
	
	else if ( (FirstBar == 1 AND Stage == 1 AND Close[i] <= ProfitPrice AND NOT High[i] >= LossPrice) OR (FirstBar == 0 AND Stage == 1 AND Low[i] <= ProfitPrice AND NOT High[i] >= TrailPrice) )
	CoverPrice[i] = ProfitPrice;
	
	else if (exitcond[i])
	coverPrice[i] = Close[i];
	
	Stage = 0;
	}














FirstBar = 0;

}

             
SetPositionSize(1, spsShares);

Hi,

Have not checked your code in detail, however able to observe some logical inconsistencies. Correct me if wrong!

  1. Assuming that you have pre-defined EntryPriceC array before entering the for-loop.

  2. What is FirstBar? I think the section of the loop that compares FirstBar == 0 never gets executed. For instances,

In the first if condition of the for-loop:

When the _Buy condition is True, FirstBar is set as 1 (True). So, the next if condition of the loop will get executed, i.e.:

My doubt is, in subsequent if conditions to follow in the for-loop, you have set a condition to check FirstBar == 0, but where and under what conditions does FirstBar resets back to 0, whilst it was set to 1 during InLong as True?

Yes. EntryPriceC and EntryPriceV are the bands of an indicator in the like of "Keltner Bands".

FirstBar is the EntryBar, where the first entry is executed. It so happens that sometimes, in the entrybar, since its a limit order, it can open at 100, go to 110, than, go down to 80 (lets say its my limit price), and close at 90.

In this case, if i put "IF HIGH >= PROFIT PRICE, SELL", since the entrybar has a big shadow that touches the Profit price, it will be set to sell = 1. And it would be wrong. So, in the entry bar, I only accept a sell in this case if the CLOSE is above the PROFIT. But, after the first bar, if the HIGH touches the PROFIT, then its valid! Get my meaning? Thats why I diferenciate firstbar (entrybar) from the rest of the bars.

Its right at the end of the loop. The last thing it will do is reset FirstBar to zero. Scroll down and you will see it.

And thanks, you helped me turn my loop way cleaner. Now what remain is to make it work the way i want.

My bad!

Well, the mismatch occurs after you have an Entry and Exit happening at the same bar. Is that right? Or are there any other occurrences?

Also have you checked the Backtester settings (System test settings window), are they all set correctly?

Would suggest you to re-write these two section of your code and handle the FirstBar separately for Long and Short Conditions. Definitely, a mix-up is happening somewhere.

  1. For Long:
  1. For Short:

To something like this:

//Also re-evaluate the conditions of this if-statement
if( ( FirstBar == 1 AND Stage == 2 AND Low[i] <= LossPrice ) OR
( FirstBar == 1 AND Stage == 2 AND Close[i] >= EntryPrice AND NOT Low[i] <= LossPrice ) OR
( FirstBar == 1 AND Stage == 1 AND Close[i] >= ProfitPrice AND NOT Low[i] <= LossPrice ) OR
( FirstBar == 0 AND Stage == 2 AND Low[i] <= LossPrice ) OR
( FirstBar == 0 AND Stage == 2 AND High[i] >= EntryPrice AND NOT Low[i] <= LossPrice ) OR
( FirstBar == 0 AND Stage == 1 AND Low[i] <= TrailPrice AND NOT Low[i] <= LossPrice ) OR
( FirstBar == 0 AND Stage == 1 AND High[i] >= ProfitPrice AND NOT Low[i] <= TrailPrice ) OR
( exitcond[i] ) )
{
    Sell[i] = 1;
    InLong = 0;

    //Avoid framing the logic this way
    /*
    if( Stage == 2 AND Low[i] <= LossPrice )
        SellPrice[i] = LossPrice;
    else
        if( ( FirstBar == 1 AND Stage == 2 AND Close[i] >= EntryPrice AND NOT Low[i] <= LossPrice ) OR( FirstBar == 0 AND Stage == 2 AND High[i] >= EntryPrice AND NOT Low[i] <= LossPrice ) )
            SellPrice[i] = EntryPrice;
        else
            if( FirstBar == 0 AND Stage == 1 AND Low[i] <= TrailPrice AND NOT Low[i] <= LossPrice )
                 SellPrice[i] = TrailPrice;
            else
                if( ( FirstBar == 1 AND Stage == 1 AND Close[i] >= ProfitPrice AND NOT Low[i] <= LossPrice ) OR( FirstBar == 0 AND Stage == 1 AND High[i] >= ProfitPrice AND NOT Low[i] <= TrailPrice ) )
                SellPrice[i] = ProfitPrice;
                else
                    if( exitcond[i] )
                        SellPrice[i] = Close[i];
	*/

	//Rather, define the above logic of this section to
	//something like this
	if( FirstBar ) //For the First Bar of the trade
    {
	    //Stages
		//Conditions and other if-else checks
		//Place order instructions accordingly
    }
	else //i.e. In trade but not the first bar
	{
		//Stages
		//Conditions and other if-else checks
		//Place order instructions accordingly
	}
    Stage = 0;
}

Then similarly make necessary changes for the Short leg of the code.

1 Like

First of all @Mrxsegredo you should follow advice given to already hundreds of times here: How do I debug my formula? - specifically use "Detailed log" as it reveals so many user mistakes and misunderstandings.

Secondly you are mistaken in first post - it does NOT close your new trade on same bar. Look at the "Ex date" column. It enters at 9:56 and exits at 10:02. That is definitely NOT the same bar.
You have TWO trades, separate. There is no scaling in. Read the manual http://www.amibroker.com/guide/h_pyramid.html

Your sigScaleIn does NOT cause scaling because previous trade is first EXITED. Then sigScaleIn without existing position is treated as normal entry (NEW, second trade).

Again - should you use Detailed log, it would become obvious to you.

1 Like

It seems Tomasz manage to unveil the mistery. eheh

I think they are, but correct me if im wrong:

settings

Yes, you are right. I followed half-advice, since I used the debugger but not the Detailed Log. Thanks for the tip.

Yes, you are right. I just saw the Detailed Log and it goes as below:

w01

Its exiting the trade and entering another, as you said. So I went to this link I saw another post in the forum http://www.amibroker.com/guide/h_portfolio.html . Went to "resolving same bar conflicts" and tried the described proccess:

Scenario 2. Both entry and exit signals are used and entry signal precedes exit signal

Used SetOption("AllowSameBarExit", True ); but the exit was still occurring before the entering. So I dropped a bit more in my detailed log and saw this:

exit

Scale-In is marked as EXIT? So Scale-In isnt an entry? Im a bit confused now. So, just to be clear, please answer this:

If I want to add to a long position, I put Buy[i] = sigScaleIn or Sell[i] = sigScaleIn?

But then, assuming it was an exit, I tried the third scenario in the link:

Scenario 3. Both signals are used and entry signal comes after exit signal.

So I added SetOption("HoldMinBars", 1 );. But, again, it exited before.

What should I do?

And complementing on the question:

codes

And thats whats happening here, so I really dont know what to do:

explorer

"Allow same bar exit" setting refers to SINGLE trade that starts and ends at the same bar. What you have here are TWO trades: one ends and another opens. This is not "same bar exit" of single trade.

Now the important part: are you registered user? Your email is not present in registered users database. We don't offer help to free riders. You have to purchase license to receive any help.

1 Like