Trailing Stop Loss

Hey guys. I've been learning about trading and coding in Amibroker.
I've put together some code based on:

  • 10 week moving average of index greater than previous week
  • Stock closing at new 20 week high
  • 20 week rate of change > 30

That part of it seemed to work ok until I started adding a trailing stop loss.
The stop loss is supposed to be based on a 40% decline from a stock's highest point unless the index is in decline (based on 10 previous 10 week's trend) in which case it moves up to a 10% decline.

All calculations are done weekly as a close of trading Friday.

When I run this as a scan, it's giving my Buy signals where the stocks don't seem to be meeting the ROC hurdle. It seemed to work ok until I added the trailing stop loss code.

Clearly I've done something(s) wrong and I'm pulling my hair out.

Any help will be much appreciated.

SetOption ( "maxopenpositions", mp = 20 );
SetPositionSize(5, spsPercentageOfEquity);

index = "INX";   // replace with your index symbol
SetForeign ( index );
{
    TimeFrameSet ( inWeekly );
    {


        Average =   MA ( C, 10 );
        buysignal =  average > Ref ( average, - 1 );
        buysignal1 =  average > Ref ( average, - 1 );      // Buy Condition #1
        uptrend = close > average;

		RestorePriceArrays();

        periodHigh = HHV ( Close, 20 );
         WeeklyClose = close;
        chg =  ROC ( Close, 20 )  ;
        buysignal2 = Close >  Ref ( periodhigh, -1 );   // Buy Condition #2
		buysignal3 = chg > 30 ;               // Buy Condition #3
		buysignal4= uptrend;
        endofweek = 1;
        
    }

    TimeFrameRestore ();
    
    buysignal = TimeFrameExpand ( buysignal , inWeekly, expandpoint );
	uptrend =   TimeFrameExpand ( uptrend , inWeekly );
	endofweek = TimeFrameExpand ( endofweek , inWeekly, expandpoint ) ;
	firstdayofweek = Ref ( endofweek, -1 );


}


Buy= buysignal1 AND buysignal2 AND buysignal3;



//Trailing Stop Information

Buy = Sell = Short = Cover = 0;
position = ExitTrade = EnterTrade = 0;
stopArray = Null ;
TrailingDistance  = IIf ( uptrend , 40 , 10 ) / 100 * Close;

//*************************************
pricecolor = colorDefault;

dow = DayOfWeek();
dt = DateTime();
dtsignal = "";

for ( i = 0 ; i < BarCount ; i ++ )
{
    if ( ExitTrade )
    {
         if ( firstdayofweek [i] )  // exit on monday
        {
            Sell [i] = 1;
            SellPrice [i] = Open[i] ;
            position = 0;
            ExitTrade = 0 ;
        }


    }

    if ( position )
    {
        if ( endofweek [i] )
        {
            if ( WeeklyClose [i ] < stop )
            {
                ExitTrade  = 1;
                pricecolor[i] = colorred;
                dtsignal = DateTimeToStr ( dt[i] );
            }


        }

        if ( ExitTrade == 0 )
        {
            stop = max ( stop , Close [i] - TrailingDistance [i] ) ;     // adjust stop
        }
    }

    if ( EnterTrade )
    {
        if ( firstdayofweek [i] )
        {
            Buy [i] = 1;
            BuyPrice[i] = Open[i];
            stop =  buyprice [i] * ( 1 - 49 / 100 ) ;  // initial stop
            position = 1;
            EnterTrade = 0;
        }


    }

    if ( !position )
    {

        if ( buysignal [i] )
        {
            //printf ( "\n" + dow[i] );
            EnterTrade = 1;
            pricecolor[i] = colorBrightGreen;

            dtsignal = DateTimeToStr ( dt[i] );
        }
    }


    if ( position )
        StopArray [i] = stop ;
}
//*****************************************

Plot ( C, "", colorDefault , stylebar );
shape = Buy *shapeUpArrow;
//Plot ( stopArray, "", colorRed , stylestaircase );
PlotShapes( shape, IIf( Buy, colorGreen, colorRed ), 0, IIf( Buy, Low, High ) );
//PlotShapes (Buy,colorGreen, 0 , Low);
//PlotShapes ( sell  shapedownArrow, colorred, 0 , high );
ribbonColor =  IIf( uptrend , colorGreen, colorRed );
Plot( 2, "", ribbonColor , styleOwnScale | styleArea | styleNoLabel, -0.5, 100 );



GraphXSpace = 10 ;
SetChartOptions( 0 , chartShowDates | chartShowArrows );

One mistake you are doing is using double restore ( TimeFrameRestore and RestorePriceArrays are equivalent). Take a look at below link showing how to apply time frame compression of foreign symbol(s)
https://www.amibroker.com/kb/2014/10/20/foreign-timeframeset/

Other than that apply debugging methods described below to know what is going on instead of doing guessing work:

1 Like

Thanks for the suggestion. I have now fixed that. But i am still having the same problem :frowning:

Hi there,

I have been coding up the following:

  • Time Frame Weekly
  • Index Filter - $SPX

Buy Conditions:

  • If Index is higher than Last weeks 20 week High
  • If 20 Week ROC is higher than 30
  • If Stock Close is above a new 20 week High

Initial Stop:

  • 40% decline on a weekly close

Trailing Stop:

  • If 10 Week Index is Up leave stop at 40%
  • If 10 Week Index is Down change stop to 10%
  • If 10 Week Index goes back up again change to 40% ONLY IF it is higher then the current 10% stop

The problem i have is the trailing stop. I don't know how to change it back to 40% ONLY IF it is higher then the current 10% stop if the Index Down filter is in effect.

Help with this would be much appreciated.

Thanks,

**


// Index Filter //


{TimeFrameSet ( inWeekly );

indexFilter = Foreign("$spx","C");	//use the $SPX as an index filter
indexUp = indexFilter > Ref ( indexFilter, - 1 ); //if the index is trading above the 10 Week MA of the index, indexUp is true
ribbonColor = IIf( indexUp , colorGreen, colorRed ); // color the ribbon. If indexUp is true, colorGreen, if not true, Red
Plot( 2, "", ribbonColor, styleArea|styleOwnScale, 0, 100); // plot the ribbon




// Buy/Sell Rules //


TimeFrameRestore();

 indexFilter =   MA ( C, 10 );
        buysignal1 =  indexFilter > Ref ( indexFilter, - 1 );      // Buy Condition #1
      	
	NewHigh = HHV ( Close, 20 );
        buysignal2 = Close >  Ref ( NewHigh, -1 );   // Buy Condition #2

	
        ROC20W30 =  ROC ( Close, 20 )  ;
        buysignal3 = ROC20W30 > 30 ;               // Buy Condition #3
        
        Buy= buysignal1 AND buysignal2 AND buysignal3;
        Sell = 0;


// Trailing Stop Loss //



InitialStopLevel = 1 - Param("Initial Trailing Stop",40,1,40,1)/100; //set initial stop level to 40%
IndexDownStopLevel = 1 - Param("Initial Trailing Stop",10,1,40,1)/100; //set secondary stop level to 10%. Used when index filter is down


trailARRAY = Null;
trailstop = 0;

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

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

//If IndexUp is fales change the trailstop to IndexDownStopLevel;



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

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

//trailstop = Max (IIF(IndexUp, InitialStopLevel,IndexDownStopLevel), (high * IIf(IndexUp, InitialStopLevel, 



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 );
}

Inside the loop that goes bar by bar, you need the code that acts on individual array elements, so something like this:

// operate on individual array elements
if( IndexUp[ i ] ) trailstop = Max( High[ i ] * InitialStopLevel, trailstop );
2 Likes

@robooooo just an observation on your strategy. Everything is Weekly (indicators/rules/orders ) Why bother using Multi-Timeframe functions when you could just run your Analysis and Backtests in a Weekly Periodicity?

4 Likes

Hi Robooooo
I have been trying to do the same thing, did you sort it out in the end?
Cheers
Wompower

HI @robooooo,

How did you go with coding this?

I'm looking at the same strategy.

Cheers.

Looks like you're implementing the Nick Radge "Weekend Trend Trader" strategy? You're a few days ahead of me on this! Would be great to hear how it performed?

I'll see if I can spot anything in the code too....

Matt, correct, and in it's most basic form, it appears to perform very well. I'm an evolving novice, so wouldn't place too much emphasis on anything I've coded so far. The trailing stop code is basically as discussed in this thread: Uses the Index filter, together with an IIF statement, to select between the TStop levels, and a looping statement handles the ratcheting.

Now trying to figure out how to enhance/filter a little more get Next Level results.

FWIW:

You could look at the ‘two moving average (close above either)’ method, it’s an adaptive type method that works quite well (especially after a decent market fall). You apply a slow moving average and a medium moving average to your index chart and if the current index close is above either of the moving averages then the index filter is on, otherwise the index filter is off.

2 Likes

@TrendSurfer, thanks for the pointer. I appreciate all and any suggestions.

Did you manage to get this to work?

Finally managed to get this to work - and Tomasz's clue in Jun 19 unraveled it for me - thanks Tom!

1 Like