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:
Appendix 4: The Easy Language Code Section can be found below. Click here and scroll there.
/*
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);
/* 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:
- LUXOR: see page 39
- Beginning of Month (chapter 5.6)
- Bollinger Band System (chapter 9)
[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;
{*******************************************************************
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 ;