I’m just getting started with AFL and I coded the simple S&P 500 Reversal system below.
If you have a moment to read it, I welcome feedback on errors and suggested improvements.
// Simple S&P 500 Reversal System -- comments at bottom after the code
SetTradeDelays( 0, 0, 0, 0 ); // no trade delays
SetOption("MaxOpenPositions", 1);
SetOption("ExtraColumnsLocation", 1 );
SetCustomBacktestProc( "" );
if ( Status( "action" ) == actionPortfolio )
{
bo = GetBacktesterObject();
bo.Backtest(); // run default backtest procedure
// read Net Profit, Winners and Losers profits from the report
st = bo.GetPerformanceStats( 0 );
netProfit = st.GetValue( "NetProfit" );
tradeProfits = st.GetValue("WinnersTotalProfit") + st.GetValue("LosersTotalLoss");
bo.AddCustomMetric( "Trading profits", tradeProfits );
bo.AddCustomMetric( "Interest earnings", netProfit - tradeProfits );
}
BuyPrice = C;
SellPrice = C;
dnPct = Optimize("DN %", 7.2, 5.0, 10.0, 0.05);
upPct = Optimize("UP %", 8.4, 5.0, 10.0, 0.05);
// prime bar 0
s105exp[0] = 1; // set initial exposure: 1 is long, 0 is out
s105stop[0] = C[0] * (1-dnPct); // set initial stop
s105Flag[0] = 1; // set initial trade flag: 1 is buy, -1 is sell, 9 is end of data and long
for( i = 1; i < BarCount; i++ )
{
if (s105exp[i-1] == 1) // if Long
{
if (C[i] >= s105stop[i-1]) // stay in -- must close under
{
s105exp[i] = 1; // maintain long
s105stop[i] = Max(s105stop[i-1],(C[i]*(1-(dnPct/100)))); // update sell stop
}
else // sell and go flat
{
s105Flag[i] = -1;
s105exp[i] = 0;
s105stop[i] = C[i]*(1+(upPct/100)); // set buy stop
}
}
else // else if out
{
if (C[i] <= s105stop[i-1]) // stay out -- must close over
{
s105exp[i] = 0;
s105stop[i] = Min(s105stop[i-1],(C[i]*(1+(upPct/100)))); // update buy stop
}
else // buy and go long
{
s105Flag[i] = 1;
s105exp[i] = 1;
s105stop[i] = C[i]*(1-(dnPct/100)); // set sell stop
}
}
}
if (s105Flag[BarCount-1] == 0) { s105Flag[BarCount-1] = 9;}
AddColumn(C,"Close",1.2);
AddColumn(s105exp, "S105 Exp", 1.0);
AddColumn(s105stop, "S105 Stop", 1.3);
AddColumn(s105Flag, "S105 Flag", 1.0 );
Buy = (s105Flag == 1);
Sell = (s105Flag ==-1);
Filter = (s105Flag != 0);
/*************************************************************************************************************************
A simple weekly reversal system for the S&P 500 Index (SPX) as an AFL coding exercise.
Backtester Periodicity set to Weekly.
Initial state set to Long.
Sell when the S&P falls -7.2% using a weekly close trailing stop.
Buy when the SPX rises +8.4% using a similar stop.
Reversal systems, by definition, won't miss a major move up or hold a major move down.
But their numerous "whipsaws" make them hard to stick with.
This concept is courtesy of Ned Davis Research and NDR Chart S105.
A similar system for the NASDAQ 100 Index is discussed on p.51 of Ned's 2014 book "Being Right or Making Money".
This code is for educational purposes only and is not intended as investment advice.
2-Nov-2017
*************************************************************************************************************************/