Trying to switch type of stop loss while in trade

I have an idea that I want to backtest but I can't quite figure out how to describe it in a way to code it. Basically what I want to do is upon entry of a long trade, I want to set a trailing stop loss of x% and then while still in the long position, I would like to switch to an ATR Trailing Stop once the ATR Trailing Stop is equal to or greater than my entry price. I currently have the ATR Trailing stop but can't figure out how to incorporate the fixed % stop and the switch. If anyone has some ideas on how to do that or could point me in a direction that might help me figure it out I would appreciate it. The current portion of my code (parts written by others and pieced together by me) that relates to this is below:

StopATRFactor = Param("Chandelier ATR multiple", 8, 0.5, 10, 0.1 );
StopATRPeriod = Param("Chandelier ATR period", 10, 3, 50 );

sup = C - StopATRFactor * ATR( StopATRPeriod );
res = C + StopATRFactor * ATR( StopATRPeriod );

// calculate trailing stop line
trailARRAY = Null;
trailstop = 0;
for( i = 1; i < BarCount; i++ )
{

if( C[ i ] > trailstop AND C[ i - 1 ] > trailstop )
trailstop = Max( trailstop, sup[ i ] );
else
if( C[ i ] < trailstop AND C[ i - 1 ] < trailstop )
trailstop = Min( trailstop, res[ i ] );
else
trailstop = IIf( C[ i ] > trailstop, sup[ i ], res[ i ] );

trailARRAY[ i ] = trailstop;
}

//generate buy/sell signals based on crossover with trail stop line
Buy = Cross( C, trailArray ) AND W52wkHigh AND UnwrappedSMA AND UpTrend; //AND Index >= IndexMA;
Sell = Cross( trailArray, C ); // OR Index < IndexMA;

1 Like

See ApplyStop.

Or modify the below code (which is from AmiBroker 'Code Snippets') to suit your exact trade specifics.

Buy = 1; // replace with your buy rule
Sell = 0; // replace with your sell rule

StopLevel = 1 - Param("trailing stop %", 3, 0.1, 10, 0.1)/100;

trailARRAY = Null;
trailstop = 0;

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

   if( trailstop == 0 AND Buy[ i ] ) 
    { 
       trailstop = High[ i ] * stoplevel;
    }
    else Buy[ i ] = 0; // remove excess buy signals

   if( trailstop > 0 AND Low[ i ] < trailstop )
    {
       Sell[ i ] = 1;
       SellPrice[ i ] = trailstop;
       trailstop = 0;
    }

   if( trailstop > 0 )
    {   
       trailstop = Max( High[ i ] * stoplevel, trailstop );
       trailARRAY[ i ] = trailstop;
    }

}

PlotShapes(Buy*shapeUpArrow,colorGreen,0,Low);
PlotShapes(Sell*shapeDownArrow,colorRed,0,High);

Plot( Close,"Price",colorBlack,styleBar);
Plot( trailARRAY,"trailing stop level", colorRed );
1 Like

Thank you...Ill go through this over the weekend and see what I can come up with

Also see this one:

Then you might want to depict the Trade prices accordingly, something like this:

_SECTION_BEGIN( "Trade Execution Prices" );
	 tn = TimeNum();

	 MultATR = Param( "ATR Multiplier", 2, 1, 4, 0.5 );
	 PerATR = Param( "ATR Period", 14, 3, 89, 1 );
	 _ATR = ATR( PerATR );
	 
	 //A Simple Demo strategy
	 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 );
	 
	 //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 ] < 144500 )
		 {
			 Buy[ i ] = 1;
			 LongFlag = 1; //To record that we are in Long position
			 BuyPrice[ i ] = HigherHighs[ i ];
		 }		 
		 if( LongFlag )
		 {
			 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 ] >= 144500 ) 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
			 
			 if( _Short[ i ] )
				 SellPrice[ i ] = LowerLows[ i ];
			 else if( L[ i ] < TSL[ i - 1 ] )
				 SellPrice[ i ] = TSL[ i - 1 ];
			 else if( tn[ i ] >= 144500 )
				 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 ] < 144500 )
		 {
			 Short[ i ] = 1;
			 ShortFlag = 1;	 //To record that we are in Short position
			 ShortPrice[ i ] = LowerLows[ i ];
		 }
		 if( ShortFlag )
		 {
			 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 ] >= 144500 ) 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
			 
			 if( Cover[ i ] )
				 CoverPrice[ i ] = HigherHighs[ i ];
			 else if( H[ i ] > TSL[ i - 1 ] )
				 CoverPrice[ i ] = TSL[ i - 1 ];
			 else if( tn[ i ] >= 144500 )
				 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, "", 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();
2 Likes

Using ParamToggle, can you have more than two options? The reason I ask is because i think I have a script that I found that has everything I want but it needs a third option added to actually do it. All of the information is there though.

SetBarsRequired(sbrAll);

StopMode = ParamToggle("Stop Mode", "Fixed|Chandelier" );
StopLevel = Param("Fixed perc %", 14, 0.1, 50, 0.1)/100;
StopATRFactor = Param("Chandelier ATR multiple", 8, 0.5, 10, 0.1 );
StopATRPeriod = Param("Chandelier ATR period", 10, 3, 50 );

// calculate support and resistance levels
if( StopMode == 0 ) // fixed percent trailing stop
{
sup = C * ( 1 - stoplevel );
res = C * ( 1 + stoplevel );
}
else // Chandelier ATR-based stop
{
sup = C - StopATRFactor * ATR( StopATRPeriod );
res = C + StopATRFactor * ATR( StopATRPeriod );
}

// calculate trailing stop line
trailARRAY = Null;
trailstop = 0;
for( i = 1; i < BarCount; i++ )
{

if( C[ i ] > trailstop AND C[ i - 1 ] > trailstop )
trailstop = Max( trailstop, sup[ i ] );
else
if( C[ i ] < trailstop AND C[ i - 1 ] < trailstop )
trailstop = Min( trailstop, res[ i ] );
else
trailstop = IIf( C[ i ] > trailstop, sup[ i ], res[ i ] );

trailARRAY[ i ] = trailstop;
}

The third option after "Fixed|Chandelier" would be "Combined". With the "Combined", I would want it to begin as a fixed % stop and then once the chandelier stop reached the purchase price, It would switch to the ATR trailing stop. Basically I am trying to hold the trailing stop closer at purchase (using the fixed &) and then as price goes up, switch to using a wider trailing stop (ATR trailing stop) to give it more room to run. I think all of that is possible with the info in this script if indeed I can create a third option with the ParamToggle.

ParamToggle only allows 2 options, but see ParamList as an alternative for more choices. Just be aware ParamList returns a String, so to get a number back from it you could do something like:

StopMode = StrToNum(StrLeft(ParamList("Stop Mode", "0. Fixed|1. Chandelier|2. Combined"), 1));
1 Like

Also see this one:

Entry & Exit in same Candle AFL Programming

If you want to delve deeper, you might consider applying a: Controlled Trailing Stop-Loss (TSL): It is necessary to ensure that TSL always goes up for Long positions and goes down for Short positions or remains constant to the previous value. "Percentage or Points" based TSLs does not account market Volatility, so it is not dynamic. "Standard Deviation" based TSL (for e.g. Kase DevStop ) or "ATR" based TSLs are ideal. For demo using ATR based TSL here: _SECTION_BEGIN( "Controlled TSL" ); Mul…

Then you might want to depict the Trade prices accordingly, something like this:

Thank you Cougar for pointing this out. This I think could be a good basis for what I am trying to do and may be able to incorporate it. The fact that it uses ATR is great which is what I have been using already. Could you give me an idea how I might modify it to do the following:

  1. On entry, set initial stop loss at X% < purchase price
  2. Once position has increased to X% above purchase, apply ATR Trailing Stop Loss

So for instance, If I enter at $30/share I want to set a stop loss at say 5% < than my entry. Then once the stock has reached 10% > than my entry, I want it to remove the 5% stop loss and begin using an (3.5, 14) ATR Trailing Stop Loss.

@MCassICT,

With the examples already given to you, you should at least try and code it yourself so others (especially those who have kindly already given you their help) can see that you are at least making an effort.

Give it a go, if you get stuck then post up your attempted code to receive further assistance.

1 Like

Try this:

_SECTION_BEGIN( "Controlled TSL" );
	 // 1. On entry, set initial stop loss at X% < purchase price
	 LevelInitTSL = Param( "Initial Stop-Loss Level (x%)", 5, 1, 5, 1 ) / 100;	 
	 // 2. Once position has increased to X% above purchase, apply ATR Trailing Stop Loss
	 LevelAtrTslSwitch = Param( "Level (x%) from Entry for TSL switch", 10, 1, 20, 1 ) / 100;
	 
	 MultATR = Param( "ATR Multiplier", 3.5, 1, 4, 0.5 );
	 PerATR = Param( "ATR Period", 14, 3, 89, 1 );
	 _ATR = ATR( PerATR );
	 
	 // A Simple Demo strategy
	 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 );
	 
	 // Array Initialization
	 Buy = Sell = Short = Cover = InitTSL = TSL = Null;
	 LongFlag = ShortFlag = 0; // Simple flag vars
	 arr = C; // Array whose value is used as reference to trigger the TSL switch
	 
	 // Using Loop to generate signals
	 for( i = 0; i < BarCount; i++ ) {
		 // Long Positions
		 if( _Buy[ i ] AND !LongFlag ) {
			 Buy[ i ] = 1;
			 LongFlag = 1; // To record that we are in Long position
			 LongEntryPrice = HigherHighs[ i ];
		 }
		 if( LongFlag ) {
			 if( arr[ i ] < LongEntryPrice * ( 1 + LevelAtrTslSwitch ) ) { // Setting-up initial stop-loss
				 InitTSL[ i ] = LongEntryPrice * ( 1 - LevelInitTSL );
				 TSL[ i ] = InitTSL[ i ];				 
				 if( TSL[ i - 1 ] > InitTSL[ i ] ) TSL[ i ] = TSL[ i - 1 ];
				 else TSL[ i ] = InitTSL[ i ];
			 }
			 else { // Switching to ATR based TSL
				 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 ] ) ) AND LongFlag ) {
			 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 ) {
			 Short[ i ] = 1;
			 ShortFlag = 1;	 // To record that we are in Short position
			 ShortEntryPrice = LowerLows[ i ];
		 }
		 if( ShortFlag ) {
			 if( arr[ i ] > ShortEntryPrice * ( 1 - LevelAtrTslSwitch ) ) { // Setting-up initial stop-loss
				 InitTSL[ i ] = ShortEntryPrice * ( 1 + LevelInitTSL );
				 TSL[ i ] = InitTSL[ i ];
				 if( TSL[ i - 1 ] < InitTSL[ i ] ) TSL[ i ] = TSL[ i - 1 ];
				 else TSL[ i ] = InitTSL[ i ];
			 }
			 else { // Switching to ATR based TSL
				 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 ] ) AND ShortFlag ) {
			 Cover[ i ] = 1; // Covering the Short position
			 ShortFlag = 0;  // Reseting ShortFlag back to False, to denote that we are no longer in "Short" position
		 }
	 }
	 
	 // Plotting
	 Plot( C, "", colorDefault, styleBar | styleThick );
	 Plot( HigherHighs, "Highs", colorDarkGreen, styleDashed | styleNoRescale );
	 Plot( LowerLows, "Lows", colorBrown, styleDashed | styleNoRescale );
	 
	 PlotShapes( IIf( Buy, shapeUpArrow, shapeNone ), colorBrightGreen, 0, L, -30 ); // Long Entry
	 PlotShapes( IIf( Sell, shapeSmallDownTriangle, shapeNone ), colorBrown, 0, H, -15 ); // Long Exit
	 
	 PlotShapes( IIf( Short, shapeDownArrow, shapeNone ), colorRed, 0, H, -30 ); // Short Entry
	 PlotShapes( IIf( Cover, shapeSmallUpTriangle, shapeNone ), colorDarkGreen, 0, L, -15 ); // Short Exit
	 
	 Plot( TSL, "TSL", colorPink, styleThick | styleNoRescale | styleNoLabel ); // Trailing Stop-Loss	 
_SECTION_END();

1

Hakuna matata.....

3 Likes

@Cougar THANK YOU! At first look this is exactly what I have been trying to do! I look forward to going through the code and comparing it to the other one you posted so that I can compare the differences so that I can see how you went about it. I have found that doing that helps me learn. Thanks again! I really appreciate your time!

1 Like

Thanks again. I spent last night and this morning going through what you've done and it works exactly the way I had hoped. You might notice, I did eliminate at least for now the short positions section since I trade long only. I have left it in the code for possible future use however. I am now trying to incorporate this into the rest of my current strategy but running into a few issues. I have tried to pay special attention trying to understand exactly how your use of looping works to identify the BUY long position. I thought I had it figured out but my modifications have caused an issue. After making the modifications I did run a code check which didnt give me any errors, but then when I added the indicator to the chart, Amibroker stopped running and I couldnt get it to recover. All I am trying to do is basically filter the buy with the trend which you can see in the modified code below. Any suggestions of what I might have done wrong?

// 52 week high/low check, within 25%
W52wkHigh = C > 0.75 * HHV(H, 52 * 5) AND C > LLV(L, 52*5)*1.30;

// Check trend using SMAs
SMA020 = MA(C, 020);
SMA050 = MA(C, 050);
SMA150 = MA(C, 150);
SMA200 = MA(C, 200);

UnwrappedSMA = C > SMA050 AND SMA050 > SMA150 AND SMA150 > SMA200;

UpTrend = SMA200 > Ref(SMA200, -22);

//Filter 
W52wkHigh AND UnwrappedSMA AND UpTrend;
	

//Index Filter//
Index = Foreign("SPY", "C", True);
IndexMA = MA(Index, 150);



_SECTION_BEGIN( "Controlled TSL" );
	 // 1. On entry, set initial stop loss at X% < purchase price
	 LevelInitTSL = Param( "Initial Stop-Loss Level (x%)", 5, 1, 10, 1 ) / 100;	 
	 // 2. Once position has increased to X% above purchase, apply ATR Trailing Stop Loss
	 LevelAtrTslSwitch = Param( "Level (x%) from Entry for TSL switch", 10, 1, 20, 1 ) / 100;
	 
	 MultATR = Param( "ATR Multiplier", 3.5, 1, 4, 0.5 );
	 PerATR = Param( "ATR Period", 14, 3, 89, 1 );
	 _ATR = ATR( PerATR );
	 
	 // A Simple Demo strategy
	 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 );
	 
	 // Array Initialization
	 Buy = Sell = Short = Cover = InitTSL = TSL = Null;
	 LongFlag = ShortFlag = 0; // Simple flag vars
	 Stage2UpTrend = W52wkHigh AND UnwrappedSMA AND UpTrend;
	 Stage2UpTrend = 0;
	 arr = C; // Array whose value is used as reference to trigger the TSL switch
	 
	 
	 // Using Loop to generate signals
	 for( i = 0; i < BarCount; i++ ) {
		 // Long Positions
		 if( _Buy[ i ] AND !LongFlag AND Stage2UpTrend)  {
			 Stage2UpTrend = 1;
			 Buy[ i ] = 1;
			 LongFlag = 1; // To record that we are in Long position
			 LongEntryPrice = HigherHighs[ i ];
		 }
		 if( LongFlag ) {
			 if( arr[ i ] < LongEntryPrice * ( 1 + LevelAtrTslSwitch ) ) { // Setting-up initial stop-loss
				 InitTSL[ i ] = LongEntryPrice * ( 1 - LevelInitTSL );
				 TSL[ i ] = InitTSL[ i ];				 
				 if( TSL[ i - 1 ] > InitTSL[ i ] ) TSL[ i ] = TSL[ i - 1 ];
				 else TSL[ i ] = InitTSL[ i ];
			 }
			 else { // Switching to ATR based TSL
				 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 ] ) ) AND LongFlag ) {
			 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 ) {
			 //Short[ i ] = 1;
			 //ShortFlag = 1;	 // To record that we are in Short position
			 //ShortEntryPrice = LowerLows[ i ];
		 }
		 //if( ShortFlag ) {
			 //if( arr[ i ] > ShortEntryPrice * ( 1 - LevelAtrTslSwitch ) ) { // Setting-up initial stop-loss
				 //InitTSL[ i ] = ShortEntryPrice * ( 1 + LevelInitTSL );
				 //TSL[ i ] = InitTSL[ i ];
				 //if( TSL[ i - 1 ] < InitTSL[ i ] ) TSL[ i ] = TSL[ i - 1 ];
				 //else TSL[ i ] = InitTSL[ i ];
			 //}
			 //else { // Switching to ATR based TSL
				 //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 ] ) AND ShortFlag ) {
			 //Cover[ i ] = 1; // Covering the Short position
			 //ShortFlag = 0;  // Reseting ShortFlag back to False, to denote that we are no longer in "Short" position
		 //}
	 //}
	 
	 // Plotting
	 Plot( C, "", colorDefault, styleBar | styleThick );
	 Plot( HigherHighs, "Highs", colorDarkGreen, styleDashed | styleNoRescale );
	 Plot( LowerLows, "Lows", colorBrown, styleDashed | styleNoRescale );
	 
	 PlotShapes( IIf( Buy, shapeUpArrow, shapeNone ), colorBrightGreen, 0, L, -30 ); // Long Entry
	 PlotShapes( IIf( Sell, shapeSmallDownTriangle, shapeNone ), colorBrown, 0, H, -15 ); // Long Exit
	 
	 PlotShapes( IIf( Short, shapeDownArrow, shapeNone ), colorRed, 0, H, -30 ); // Short Entry
	 PlotShapes( IIf( Cover, shapeSmallUpTriangle, shapeNone ), colorDarkGreen, 0, L, -15 ); // Short Exit
	 
	 Plot( TSL, "TSL", colorLightBlue, styleLine | styleNoRescale | styleNoLabel ); // Trailing Stop-Loss	 
_SECTION_END();

(To give proper credit, the first part of this code was written by @rocketPower and also may include minor modifications by me)

Untested, but try and add your buy conditions to the "_Buy" variable.

_Buy = Cross( H, Ref( HigherHighs, -1 ) ) AND Stage2Uptrend;

Thanks @Metamega! That's frustrating....LOL. That was the direction I had initially taken last night but it wasn't working. I knew it had to be simple. When I tried that before, I must have had something not quite right. Your suggestions was spot on though. Not sure what the difference was. Thank you!

@MCassICT,

Noticed few things in your code:

  1. Unassigned Boolean condition.
//Filter 
W52wkHigh AND UnwrappedSMA AND UpTrend;
  1. Reassignment to 0 just after setting it.
Stage2UpTrend = W52wkHigh AND UnwrappedSMA AND UpTrend;
Stage2UpTrend = 0;

Stage2UpTrend = W52wkHigh AND UnwrappedSMA AND UpTrend becomes meaningless the moment you set it to 0 in next line.

  1. Calling the array in a loop instead of looking into its elements bar-by-bar.
if( _Buy[ i ] AND !LongFlag AND Stage2UpTrend)  {
  1. Incorrect use of an Array like a flag variable.
if( _Buy[ i ] AND !LongFlag AND Stage2UpTrend)  {
Stage2UpTrend = 1;

Stage2UpTrend is a bar-by-bar array of Bools i.e. 0 when False (condition(s) not met) or 1 when True (condition(s) met), you previously set it to W52wkHigh AND UnwrappedSMA AND UpTrend. Now that since you set it to 1 from inside the if check, once again the essence of Stage2UpTrend is lost and trade occurs whenever just the Cross( H, Ref( HigherHighs, -1 ) ) condition is met. Logically redundant!


So after removing the unnecessary stuffs, this is how it looks:

// 52 week high/low check, within 25%
W52wkHigh = C > 0.75 * HHV( H, 52 * 5 ) AND C > LLV( L, 52 * 5 ) * 1.30;

// Check trend using SMAs
SMA050 = MA( C, 50 );
SMA150 = MA( C, 150 );
SMA200 = MA( C, 200 );
UnwrappedSMA = C > SMA050 AND SMA050 > SMA150 AND SMA150 > SMA200;
UpTrend = SMA200 > Ref( SMA200, -22 );

_SECTION_BEGIN( "Controlled TSL" );
	 Per = Param( "Swing Period", 15, 3, 144, 1 );
	 LevelInitTSL = Param( "Initial Stop-Loss Level (x%)", 5, 1, 10, 1 ) / 100;
	 LevelAtrTslSwitch = Param( "Level (x%) from Entry for TSL switch", 10, 1, 20, 1 ) / 100;

	 MultATR = Param( "ATR Multiplier", 3.5, 1, 4, 0.5 );
	 PerATR = Param( "ATR Period", 14, 3, 89, 1 );
	 _ATR = ATR( PerATR );

	 // A Simple Demo strategy
	 HigherHighs = HHV( H, Per );
	 LowerLows = LLV( L, Per );
	 _Buy = Cross( H, Ref( HigherHighs, -1 ) );
	 _Sell = Cross( Ref( LowerLows, -1 ), L );	 

	 // Array Initialization
	 Buy = Sell = InitTSL = TSL = Null;
	 LongFlag = ShortFlag = 0; // Simple flag vars
	 Stage2UpTrend = W52wkHigh AND UnwrappedSMA AND UpTrend;
	 arr = C; // Array whose value is used as reference to trigger the TSL switch

	 // Using Loop to generate signals
	 for( i = 0; i < BarCount; i++ ) {
		 // Long Positions
		 if( _Buy[ i ] AND Stage2UpTrend[ i ] AND !LongFlag ) {
			 Buy[ i ] = 1;
			 LongFlag = 1; // To record that we are in Long position
			 LongEntryPrice = HigherHighs[ i ];
		 }

		 if( LongFlag ) {
			 if( arr[ i ] < LongEntryPrice * ( 1 + LevelAtrTslSwitch ) ) { // Setting-up initial stop-loss
				 InitTSL[ i ] = LongEntryPrice * ( 1 - LevelInitTSL );
				 TSL[ i ] = InitTSL[ i ];

				 if( TSL[ i - 1 ] > InitTSL[ i ] ) TSL[ i ] = TSL[ i - 1 ];
				 else TSL[ i ] = InitTSL[ i ];
			 }
			 else { // Switching to ATR based TSL
				 if( TSL[ i - 1 ] > H[ i ] - _ATR[ i ] * MultATR ) TSL[ i ] = TSL[ i - 1 ];
				 else TSL[ i ] = H[ i ] - _ATR[ i ] * MultATR;
			 }
		 }

		 if( ( _Sell[ i ] OR L[ i ] < TSL[ i - 1 ] ) AND LongFlag ) {
			 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
		 }
	 }

	 // Plotting
	 Plot( C, "Price", colorDefault, styleBar | styleThick );
	 Plot( HigherHighs, "Highs", colorDarkGreen, styleDashed | styleNoRescale );
	 Plot( LowerLows, "Lows", colorBrown, styleDashed | styleNoRescale );

	 PlotShapes( IIf( Buy, shapeUpArrow, shapeNone ), colorBrightGreen, 0, L, -30 ); // Long Entry
	 PlotShapes( IIf( Sell, shapeSmallDownTriangle, shapeNone ), colorBrown, 0, H, -15 ); // Long Exit	 

	 Plot( TSL, "TSL", colorLightBlue, styleLine | styleNoRescale | styleNoLabel ); // Trailing Stop-Loss
_SECTION_END();

Otherwise as pointed out by @Metamega you can also write as below but need to take care of other unnecessary logic:

// 52 week high/low check, within 25%
W52wkHigh = C > 0.75 * HHV( H, 52 * 5 ) AND C > LLV( L, 52 * 5 ) * 1.30;

// Check trend using SMAs
SMA050 = MA( C, 50 );
SMA150 = MA( C, 150 );
SMA200 = MA( C, 200 );
UnwrappedSMA = C > SMA050 AND SMA050 > SMA150 AND SMA150 > SMA200;
UpTrend = SMA200 > Ref( SMA200, -22 );

_SECTION_BEGIN( "Controlled TSL" );
	 Per = Param( "Swing Period", 15, 3, 144, 1 );
	 LevelInitTSL = Param( "Initial Stop-Loss Level (x%)", 5, 1, 10, 1 ) / 100;
	 LevelAtrTslSwitch = Param( "Level (x%) from Entry for TSL switch", 10, 1, 20, 1 ) / 100;

	 MultATR = Param( "ATR Multiplier", 3.5, 1, 4, 0.5 );
	 PerATR = Param( "ATR Period", 14, 3, 89, 1 );
	 _ATR = ATR( PerATR );

	 // Array Initialization
	 Buy = Sell = InitTSL = TSL = Null;
	 LongFlag = ShortFlag = 0; // Simple flag vars
	 Stage2UpTrend = W52wkHigh AND UnwrappedSMA AND UpTrend;
	 arr = C; // Array whose value is used as reference to trigger the TSL switch
	 
	 // A Simple Demo strategy
	 HigherHighs = HHV( H, Per );
	 LowerLows = LLV( L, Per );
	 _Buy = Cross( H, Ref( HigherHighs, -1 ) ) AND Stage2UpTrend;
	 _Sell = Cross( Ref( LowerLows, -1 ), L );	 

	 // Using Loop to generate signals
	 for( i = 0; i < BarCount; i++ ) {
		 // Long Positions
		 if( _Buy[ i ] AND !LongFlag ) {
			 Buy[ i ] = 1;
			 LongFlag = 1; // To record that we are in Long position
			 LongEntryPrice = HigherHighs[ i ];
		 }

		 if( LongFlag ) {
			 if( arr[ i ] < LongEntryPrice * ( 1 + LevelAtrTslSwitch ) ) { // Setting-up initial stop-loss
				 InitTSL[ i ] = LongEntryPrice * ( 1 - LevelInitTSL );
				 TSL[ i ] = InitTSL[ i ];

				 if( TSL[ i - 1 ] > InitTSL[ i ] ) TSL[ i ] = TSL[ i - 1 ];
				 else TSL[ i ] = InitTSL[ i ];
			 }
			 else { // Switching to ATR based TSL
				 if( TSL[ i - 1 ] > H[ i ] - _ATR[ i ] * MultATR ) TSL[ i ] = TSL[ i - 1 ];
				 else TSL[ i ] = H[ i ] - _ATR[ i ] * MultATR;
			 }
		 }

		 if( ( _Sell[ i ] OR L[ i ] < TSL[ i - 1 ] ) AND LongFlag ) {
			 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
		 }
	 }

	 // Plotting
	 Plot( C, "Price", colorDefault, styleBar | styleThick );
	 Plot( HigherHighs, "Highs", colorDarkGreen, styleDashed | styleNoRescale );
	 Plot( LowerLows, "Lows", colorBrown, styleDashed | styleNoRescale );

	 PlotShapes( IIf( Buy, shapeUpArrow, shapeNone ), colorBrightGreen, 0, L, -30 ); // Long Entry
	 PlotShapes( IIf( Sell, shapeSmallDownTriangle, shapeNone ), colorBrown, 0, H, -15 ); // Long Exit	 

	 Plot( TSL, "TSL", colorLightBlue, styleLine | styleNoRescale | styleNoLabel ); // Trailing Stop-Loss
_SECTION_END();

Few suggestions:

  1. Whenever in trouble use DebugView and/or Exploration for debugging your code. It will easily enable you to visualize the problem and hence solve it.
  2. Please thoroughly read Understanding how AFL works.
  3. Also read Type coercion in AFL.
4 Likes