Move profit target and stop loss after initial profit target is hit

I have the following amibroker afl backtesting code with stop-loss set at 10 points and profit target set at 20 points.

long_entry_condition = close > EMA(50);
Buy = long_entry_condition;
BuyPrice = IIf(Buy == True, TrueArray=ValueWhen(long_entry_condition, close), FalseArray=0); 

risk = 10;

ApplyStop(Type=stopTypeLoss, mode=stopModePoint, Amount=risk, 
            ExitAtStop=1, volatile=False, ReEntryDelay=0, ValidFrom=0, ValidTo=-1 );
ApplyStop(Type=stopTypeProfit, mode=stopModePoint, Amount=2*risk, 
            ExitAtStop=1, volatile=False, ReEntryDelay=0, ValidFrom=0, ValidTo=-1 );
        

Suppose I want to take profit for half the position at 10 points. Then for the remaining half position, I want to set the stop loss level to breakeven and the profit target at 30 points. How do I modify the existing code to achieve this?

ApplyStop only handles stops that are the same for a trade. You can't have different ApplyStop different for "one half" and the "other half".
The only way to achieve what you want is to use custom backtester code and implement stops in the code.

Search the Knowledge Base for custom backtester code examples.

Note that your BuyPrice array assignment is wrong. It should be just BuyPrice = Close. Also your EMA call is incorrect. Also incorrect is the IIF() call. Don't use assignments in place of function call arguments. Don't use Pythonesque syntax for function calls. AFL is not Python. Before posting anything on the forum make sure you don't get ANY error messages. You do have errors and warnings now:

1 Like

Tomasz, I found this example in amibroker guide h_pyramid.html.

Do you think example code below is good enough as reference code for my need instead of custom backtester? I prefer a simpler solution.

Example 4: partial exit (scaling out) on profit target stops

Example of code that exits 50% on first profit target, 50% on next profit target and everything at trailing stop:


Buy = Cross( MA( C, 10 ), MA( C, 50 ) );
Sell = 0;

// the system will exit
// 50% of position if FIRST PROFIT TARGET stop is hit
// 50% of position is SECOND PROFIT TARGET stop is hit
// 100% of position if TRAILING STOP is hit

FirstProfitTarget = 10; // profit
SecondProfitTarget = 20; // in percent
TrailingStop = 10; // also in percent

priceatbuy=0;
highsincebuy = 0;

exit = 0;

for( i = 0; i < BarCount; i++ )
{
   if( priceatbuy == 0 AND Buy[ i ] )
    {
       priceatbuy = BuyPrice[ i ];
    }

   if( priceatbuy > 0 )
    {
       highsincebuy = Max( High[ i ], highsincebuy );

      if( exit == 0 AND
          High[ i ] >= ( 1 + FirstProfitTarget * 0.01 ) * priceatbuy )
       {
         // first profit target hit - scale-out
         exit = 1;
         Buy[ i ] = sigScaleOut;
       }

      if( exit == 1 AND
          High[ i ] >= ( 1 + SecondProfitTarget * 0.01 ) * priceatbuy )
       {
         // second profit target hit - exit
         exit = 2;
         SellPrice[ i ] = Max( Open[ i ], ( 1 + SecondProfitTarget * 0.01 ) * priceatbuy );
       }

      if( Low[ i ] <= ( 1 - TrailingStop * 0.01 ) * highsincebuy )
       {
         // trailing stop hit - exit
         exit = 3;   
         SellPrice[ i ] = Min( Open[ i ], ( 1 - TrailingStop * 0.01 ) * highsincebuy );
       }

      if( exit >= 2 )
       {
         Buy[ i ] = 0;
         Sell[ i ] = exit + 1; // mark appropriate exit code
         exit = 0;
         priceatbuy = 0; // reset price
         highsincebuy = 0;
       }
    }
}

SetPositionSize( 50, spsPercentOfEquity );
SetPositionSize( 50, spsPercentOfPosition * ( Buy == sigScaleOut ) ); // scale out 50% of position

Yes, you can use loop instead of CBT if you wish.

1 Like

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