Profit Stop Loop

About 3/4 of the way down this page, there is an example of a profit target stop using a loop.
http://www.amibroker.com/guide/h_backtest.html

And this is the code:

/* a sample low-level implementation of Profit-target stop in AFL: */ 

Buy = Cross( MACD(), Signal() ); 

priceatbuy=0; 

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

     if( priceatbuy > 0 && SellPrice[ i ] > 1.1 * priceatbuy ) 
     { 
       Sell[ i ] = 1; 
       SellPrice[ i ] = 1.1 * priceatbuy; 
       priceatbuy = 0; 
     } 
     else 
       Sell[ i ] = 0; 
} 

I tested it and I found that several things didn't work correctly for me. I'm posting what I figured out to share and to invite comments.

The code uses

if( priceatbuy > 0 && SellPrice[ i ] > 1.01 * priceatbuy )

It will exit intraday, but only if the close price exceeds the profit target price. I changed it to

if( priceatbuy > 0 && High[ i ] > 1.01 * priceatbuy)

In this line:

SellPrice[ i ] = 1.01 * priceatbuy;

If the open, is higher than the target price, it will give an unrealistic exit right at the target price. I changed it to this:

SellPrice[ i ] = Max(1.01 * priceatbuy, Open[i]);

Then I saw the occasional instance, where you could get an exit at the open or intraday and then a buy at the end of that same day. That would be a realistic trade, but in that instance, it wouldn't pick up that day's close as the correct price for "priceatbuy" I added these two lines to correct for that situation:

     if( Buy[ i ] ) 
     priceatbuy = BuyPrice[ i ];

This is the final code that I made:

///@link http://www.amibroker.com/guide/h_backtest.html
/* a sample low-level implementation of Profit-target stop in AFL: */ 

Buy = Cross( MACD(), Signal() ); 

priceatbuy=0; 

for( i = 0; i < BarCount; i++ ) 
{ 

     if( priceatbuy == 0 && Buy[ i ] ) 
     priceatbuy = BuyPrice[ i ]; 

     if( priceatbuy > 0 && High[ i ] > 1.01 * priceatbuy) //changed from SellPrice to High otherwise it can miss profit target sells, changed from 1.1 to 1.01 to show more trades 
     { 
       Sell[ i ] = 1; 
       SellPrice[ i ] = Max(1.01 * priceatbuy, Open[i]); //original code exits only at exact target price, not realistic if it opens higher than the target, changed from 1.1 to 1.01 to show more trades
       priceatbuy = 0; 
       
     if( Buy[ i ] ) //occasionally you get a buy on the close after a target hit, but the priceatbuy will be set to 0, added this line and the next to retain the priceatbuy
     priceatbuy = BuyPrice[ i ];
     } 
     else 
       Sell[ i ] = 0;
    
}
Short = Cover = 0; 

//charting
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( Close, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() ); 
// Plot Buy and Sell Signal Arrows 
PlotShapes(IIf(Buy, shapeSquare, shapeNone),colorGreen, 0, L, Offset=-40);
PlotShapes(IIf(Buy, shapeSquare, shapeNone),colorLime, 0,L, Offset=-50);
PlotShapes(IIf(Buy, shapeUpArrow, shapeNone),colorWhite, 0,L, Offset=-45);
PlotShapes(IIf(Sell, shapeSquare, shapeNone),colorRed, 0, H, Offset=40);
PlotShapes(IIf(Sell, shapeSquare, shapeNone),colorOrange, 0,H, Offset=50);
PlotShapes(IIf(Sell, shapeDownArrow, shapeNone),colorWhite, 0,H, Offset=-45);

For my code to work as expected, the buy trade delay should be set to 0 and the BuyPrice should be set to Close. The sell delay and SellPrice don't matter as they are controlled in the code. Alternatively, add this line at the start of the code:

SetTradeDelays( 0, 0, 0, 0 );
BuyPrice = Close;

Which should give you this final code:

///@link http://www.amibroker.com/guide/h_backtest.html
/* a sample low-level implementation of Profit-target stop in AFL: */   

SetTradeDelays( 0, 0, 0, 0 );
BuyPrice = Close;

Buy = Cross( MACD(), Signal() ); 

priceatbuy=0; 

for( i = 0; i < BarCount; i++ ) 
{ 

     if( priceatbuy == 0 && Buy[ i ] ) 
     priceatbuy = BuyPrice[ i ]; 

     if( priceatbuy > 0 && High[ i ] > 1.01 * priceatbuy) //changed from SellPrice to High otherwise it can miss profit target sells, changed from 1.1 to 1.01 to show more trades 
     { 
       Sell[ i ] = 1; 
       SellPrice[ i ] = Max(1.01 * priceatbuy, Open[i]); //original code exits only at exact target price, not realistic if it opens higher than the target, changed from 1.1 to 1.01 to show more trades
       priceatbuy = 0; 
       
     if( Buy[ i ] ) //occasionally you get a buy on the close after a target hit, but the priceatbuy will be set to 0, added this line and the next to retain the priceatbuy
     priceatbuy = BuyPrice[ i ];
     } 
     else 
       Sell[ i ] = 0;
    
}
Short = Cover = 0; 

//charting
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( Close, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() ); 
// Plot Buy and Sell Signal Arrows 
PlotShapes(IIf(Buy, shapeSquare, shapeNone),colorGreen, 0, L, Offset=-40);
PlotShapes(IIf(Buy, shapeSquare, shapeNone),colorLime, 0,L, Offset=-50);
PlotShapes(IIf(Buy, shapeUpArrow, shapeNone),colorWhite, 0,L, Offset=-45);
PlotShapes(IIf(Sell, shapeSquare, shapeNone),colorRed, 0, H, Offset=40);
PlotShapes(IIf(Sell, shapeSquare, shapeNone),colorOrange, 0,H, Offset=50);
PlotShapes(IIf(Sell, shapeDownArrow, shapeNone),colorWhite, 0,H, Offset=-45);
1 Like