Appendix 5: AmiBroker Code Section          

Here you find the free AmiBroker codes for the two systems which we described and used in the book "Trading Systems, 2nd edition" as examples:

  1.  Beginning of Month (chapter 5.6)
  2.  Bollinger Band System (chapter 9)

Appendix 4: The Easy Language Code Section can be found below. Click here and scroll there.

  1. Beginning of Month :

/*

Beginning of Month Trading System

FOR EDUCATIONAL USE ONLY

Coded for AmiBroker by Urban Jaekle, 9 Sept 2018, updated 14 Apr 2021

wwww.urban-stocks.com

Idea: Buy a stock index on each last day of the month on close, if it

trades above the 40 day moving average. Hold it for 4 days.

Exit on the fourth trading day on close or when the market closes

below the 40 day moving // average Apply to daily data,

stock indices like S&P500, DAX, Nifty50, World ex US, REIT etc.

##########      general settings        #################

number of positions, initial equity, commission amount etc

*/

NumberPositions = 1;

SetOption("MaxOpenPositions", NumberPositions);

PositionSize = -100 / NumberPositions;

InitialEquity = 100000;

CompoundedProfits = 1; /*1 = yes, 0 = no  */

CommissionAmount = 20; /* means 40$ per round turn */

SetOption( "InitialEquity", InitialEquity ); 

SetOption( "CommissionMode", 2 ); /*  1 = percent, 2 = fixed */

SetOption( "CommissionAmount", CommissionAmount ); 

/*   define the last trading day of the month for the entry  */

isLastOfMonth = TimeframeExpand(1, inMonthly, expandPoint);

/* for exit and entry filter: optimization of mov. average length */

MAExit = optimize( "MAExit", 40, 10,300, 10 );

IndexFilterLength = MAExit;  

IndexUPTrend = C > MA(C,IndexFilterLength); 

PositionScore = 100 + Ref(ROC(C, 252),-1); 

/* Add this line for selecting the strongest

Index within an index portfolio */

Buy= isLastOfMonth AND IndexUPTrend;

Sell = Cross( MA( Close,MAExit ), Close) ;  

BuyPrice=SellPrice=Close; 

Short=Cover=0; 

/* Exit Trade after X Bars; default = 4 days */

/*NumBarExit = optimize( "NumBarExit", 4, 1, 20, 1 ); 

  if you want to optimize */

NumBarExit = 4; 

ApplyStop( stopTypeNBar, stopModeBars, NumBarExit );

/*    For visualization */

Plot(C,"Close", colorBlack, styleCandle);

Plot(MA( Close,MAExit ),"MA Exit", colorBlue, styleThick);


  1. Bollinger Band System (chapter 9):

/* Bollinger Band Trading Strategy

 FOR EDUCATIONAL USE ONLY

 Coded for AmiBroker by Urban Jaekle, 20 Nov 2018

 wwww.urban-stocks.com

 The system buys on the OPEN of today if yesterday's close was above

 the Bollinger Band Top

 Apply to daily data, e.g. all stocks incl. delisted of the S&P500,

Nasdaq100, Russell2000 etc.

 For optimisation:

variable = optimize( "Description", default, min, max, step );

 see also this: https://norgatedata.com/AmiBroker-usage.php */

/*include all Norgate functions for survivorship free backtests */

#include_once "Formulas\Norgate Data\Norgate Data Functions.afl";

/* General settings */

index = "$SPX";      /* choose index which you test;

don't forget this to set also in backtester settings "pad and align"!

e.g. Norgate symbols $SPX=S&P500, $SP1500=S&P1500,

 $NDX=Nadaq100, $DJI=DowJones 30, $RUI = Russell 1000, $RUT=Russell 2000,

 $RUA= Russell 3000, $XAO.au = Sidney All Ordinaries 500      

more see https://norgatedata.com/data-content-tables.php; */

/* Strategy parameters */

NumberPositions      = 20;

/* Number of positions which you can hold at the same time*/

BollTopPrds              = 180;

/*compare with Appendix 1. Futures: default = 60 */

BollingerTopWidth  = 3.5; 

/* For entry, compare with Appendix 1. Futures: default = 2 */

/* BollingerTopWidth= Optimize (3.5, 0.5, 7, 0.5); // Select this line for optimisation Optimize (default, min, max, step)  */

 

BollBottWdth            = 0.5;

/*For exit, compare with Appendix 1. Futures: default = 2 (for shorts) */

IndexFilterLength    = 300;  /*set Filter Length*/

ScoreLength              = 300;  /*Score lenght */

BollBottPrds  = BollTopPrds; /*same length for both bands*/

SetOption("MaxOpenPositions", NumberPositions); 

SetPositionSize(100 / NumberPositions, spsPercentOfEquity); 

InitialEquity = 100000;

CommissionAmount = 0.25;

/*this means 0.25% at entry AND 0.25% at exit of a position */

SetOption( "InitialEquity", InitialEquity );

SetOption( "CommissionMode", 1 ); /*1 = percent, 2 = fixed */

SetOption( "CommissionAmount", CommissionAmount );

RoundLotSize = 0;

/* 0: fractional number of shares are allowed */

/* Preparation for Entry and Exit */

indexFilter     = NorgateIndexConstituentTimeSeries(index);

upperBand    = BBandTop(C, BollTopPrds, BollingerTopWidth);

LongEntry = C >upperBand          /* Price is above the upper Bollinger band */

AND Ref(C<upperBand, -1)          

/* Price the day before is below the upper Bollinger band */

AND indexFilter;

/* make sure you have the correct stock universe */

LongExit = C < BBandBot(C, BollBottPrds, BollBottWdth);

/* price is below the bottom Bollinger band */

/* Market index filter. Allow positions only when index is in uptrend,

defined by a simple moving average of 300 days*/

SetForeign(index);

/*Norgate $SPX, $SP1500, $NDX, $DJI, $RUT=Russell 2000,

$RUA= Russell 3000, Sidney All Ordinaries

(Australian stock market)       $XAO.au

see here https://norgatedata.com/data-content-tables.php;

                                                                       */

IndexDownTrend = C < MA(C,IndexFilterLength);

/*IndexDownTrend = LinRegSlope(C, IndexFilterLength) ;

//  another possible option to define trend */

RestorePriceArrays();

/* In the case you get many different signals, buy the

stocks with the highest momentum over the last 300 days first*/

Rank = 100 + Ref(ROC(C, ScoreLength),-1);     

PositionScore = Rank;

/* The entry and exit trigger */

Buy = LongEntry               

/* Price is today above the Bollinger band */

AND !IndexDownTrend;  

/* Index Filter: Don't enter new positions in a bear market */  

Sell =  LongExit

OR DateTime()==GetFnData("DelistingDate")

 /* sell if stock is de-listed */

OR !indexFilter ;     

/* sell if stock has to leave the index  */

BuyPrice=SellPrice=Open;  /* Buy and Sell on the next days open;

Close instead of open could improve performance */

Short = Cover = 0;

/* for visualisation, optional */

Plot(C,"Close", colorBlack, styleCandle);

Plot(BBandTop(C, BollTopPrds, BollingerTopWidth),

"BollEntry", colorGreen, styleThick);

Plot(BBandBot(C, BollBottPrds, BollBottWdth),"BollExit"

, colorRed, styleThick);

Plot(ma(CLOSE, BollTopPrds),"MovAvg", colorBlack, styleThick); 

 

 

Appendix 4: Easy Language Code Section          

 

Here you find the free EasyLanguage codes for the systems which we described and used in this book as examples:

  1. LUXOR: see page 39
  2. Beginning of Month (chapter 5.6)
  3. Bollinger Band System (chapter 9)
  1. Beginning of Month (chapter 5.6):

 [LegacyColorValue = true];

 

{ FOR EDUCATIONAL USE ONLY

 Coded for TradeStation by Urban Jaekle, 20 Feb 2018

// wwww.urban-stocks.com

 

This is the system called "time" because time (!!!) is the only important parameter for it

Some facts about the system:

1) Only end of day data is needed to trade the system

2) It produces long entries for any stock index future,

e.g. S&P500, Nasdaq, Russel2000, EuroStoxx, DAX, Nikkei, HangSeng, KOSPI, SMI etc.

3) All trades are exited after a hold period of 4 days or if being stopped out by the initial stop

// Idea: Buy a stock index on each last day of the month on close, if it trades above the 40

// day moving average. Hold it for 4 days.

// Exit on the fourth trading day on close or when the market closes below the 40 day moving // average}

{################# Let's start with the inputs for the intial stop ################}

Inputs:  MovAvgPeriods(40);

Variables: BullishPoint(0);

 

BullishPoint= Average( Close, MovAvgPeriods );

{################# Now the time settings, trade only at special days ##############}

If C > BullishPoint AND

           

((DayOfMonth(Date)=29 AND DayOfWeek(Date)=5) OR

(DayOfMonth(Date)=30 AND

(Month(Date)=4 OR Month(Date)=6 OR Month(Date)=9 OR Month(Date)=11))

 OR

DayOfMonth(Date)=31 OR

(DayOfMonth(Date)=28 AND Month(Date)=2) OR

(DayOfMonth(Date)=28 AND (Month(Date)=4 OR Month(Date)=6

OR Month(Date)=9 OR Month(Date)=11) AND DayOfWeek(Date)=5)

OR (DayOfMonth(Date)=30 AND DayOfWeek(Date)=5)

OR (DayOfMonth(Date)=29 AND Month(Date)=2)

OR (DayOfMonth(Date)=27 AND Month(Date)=2 AND DayOfWeek(Date)=5)

OR (DayOfMonth(Date)=26 AND Month(Date)=2 AND DayOfWeek(Date)=5))

 

then Buy("BuyDay") this bar on close;

{#### And finally the exit:

If the market closes below the 40day average: exit next bar on close

 

After 4 days if not being stopped out before#######}

 

If C<BullishPoint then Sell("MovAvgExit") this bar on close;

 

If BarsSinceEntry=4 then Sell("4days") this bar on close;


  1. Bollinger Band System (chapter 9):

{*******************************************************************

Description     : Bollinger Band System

Coded for TradeStation by Urban Jaekle, 20 Dec 2018 // wwww.urban-stocks.com

FOR EDUCATIONAL USE ONLY

********************************************************************}

[LegacyColorValue = true];

{Inputs###############################################################}

Inputs: BarsBlw(2), Length( 180 ), NumDevsUp( 3 ) , NumDevsDn( 1 ) ;

{Define Bollinger bands #############################################}

variables:       UpperBand( 0 ), LowerBand( 0 ) ;

 

UpperBand = BollingerBand( C, Length, NumDevsUp ) ;

 

LowerBand = BollingerBand( C, Length, NumDevsDn ) ;

{######### entry and exit#######################################}

If CountIF(Close < UpperBand, BarsBlw) = BarsBlw Then

            Buy ("BB") Next Bar at UpperBand Stop;

 

if CurrentBar > 1 and C crosses under LowerBand then

{ CB > 1 check used to avoid spurious cross confirmation at CB = 1 }

            sell ( "BBandexit" ) next bar at LowerBand stop ;