This page is under construction.
Plans include to add:
- A brief discussion of the system, including
- where the system is taken from
- entry and exit rules
- position sizing, etc
- Backtesting results
Systems
Adaptive Price Zone
//AdaptivePriceZone.afl
//Taken from Quantitative Trading System (2nd Edition) by Howard Bandy Pg 148
//Trading system based on Lee Leibfarth's Trading with An Adaptive Price Zone
//TASC September 2006 Issue
function DblSmoothEMA(price, length)
{
period = IIf(Length < 0, 1, sqrt(Length));
smooth = 2 / (period + 1);
return AMA( AMA(price, smooth), smooth);
}
SetTradeDelays(0,0,0,0);
BuyPrice = C;
SellPrice = C;
price = C;
period = 50;
BandPct = 2;
DsEMA = DblSmoothEMA(price, period);
RangeDsEMA = DblSmoothEMA(H-L, period);
UpBand = BandPct * RangeDsEMA + DsEMA;
DnBand = DsEMA - BandPct * RangeDsEMA;
ADXThshold = 30;
ADXLength = 14;
ADXValue = ADX(ADXLength);
Buy = ADXValue <= ADXThshold AND Low <= DnBand;
Sell = ADXValue > ADXThshold;
Buy = ExRem(Buy, Sell);
Sell = ExRem(Sell, Buy);
Plot(UpBand, "UpBand", colorLightGrey);
Plot(DnBand, "DownBand", colorLightGrey);
PlotShapes(Buy*shapeUpArrow, colorGreen, 0, DnBand, -24);
PlotShapes(Sell*shapeDownArrow, colorRed, 0, UpBand, -24);
PIRDPO
/*DetrendedPriceOscillator_System.afl
Compute and plot the high frequency residual after detrending */
// Copied or adapted from Mean Reversion Trading Systems by Howard Bandy
eq = Param("Fixed Equity", 100000, 1, 10000000);
percentEQ = Param("Percentage of EQ to risk", 1, 0.01, 1, 0.01);
SetOption("ExtraColumnsLocation", 1);
SetOption("CommissionMode", 2); //$ per trade
SetOption("CommissionAmount", 5);
SetOption("InitialEquity", eq);
SetPositionSize(percentEQ*eq, spsValue);
MaxPos = 1;
SetOption("MaxOpenPositions", MaxPos);
SetBacktestMode(backtestRegularRawMulti);
SetTradeDelays(0,0,0,0);
BuyPrice = SellPrice = Close;
function PIR(p, Length)
{
//compute the PIR of series p, relative to its position over a lookback window of Length
ll = LLV(p, Length);
hh = HHV(p, Length);
return 100*(p-ll)/(hh-ll);
}
MA1Length = Optimize("MA1Length", 3, 1, 50, 1);
PIRLength = Optimize("PIRLength", 12, 2, 30, 1);
BuyLevel = Optimize("BuyLevel", 10, 1, 30, 1);
MA1 = MA(C, MA1Length);
DPO = (C-MA1) / MA1;
PIRDPO = PIR(DPO, PIRLength);
Buy = PIRDPO < BuyLevel;
Sell = BarsSince (Buy) >= 3;
//Plot Price
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
Plot(MA1, "MA1", colorBlue, styleLine|styleThick);
Plot(PIRDPO, "PIRDPO", colorGreen, styleLine|styleOwnScale, 0, 100);
Connors RSI Pullback
//ConnorsRSIPullback.afl
//ConnorsRSI is defined in "An introduction of ConnorsRSI" published by TradingMarkets.
/////////////////////////// System Settings ///////////////////////////
OptimizerSetEngine("cmae");
eq = Param("Fixed Equity", 100000, 1, 10000000);
percentEQ = Param("Percentage of EQ to risk", 1, 0.01, 1, 0.01);
SetOption("ExtraColumnsLocation", 1);
SetOption("CommissionMode", 2); //$ per trade
SetOption("CommissionAmount", 5);
SetOption("InitialEquity", eq);
SetPositionSize(percentEQ*eq, spsValue);
MaxPos = 1;
SetOption("MaxOpenPositions", MaxPos);
SetBacktestMode(backtestRegularRawMulti);
SetTradeDelays(0,0,0,0);
BuyPrice = SellPrice = Close;
/////////////////////////// User Functions ///////////////////////////
function StreakDuration(p)
{
t[0] = 0;
for (i = 1; i < BarCount; i++)
{
t[i] = 0;
if (p[i] > p[i-1])
if (t[i-1] >= 0)
t[i] = t[i-1] + 1;
else
t[i] = 1;
else if (p[i] < p[i-1])
if (t[i-1] <= 0)
t[i] = t[i-1] - 1;
else
t[i] = -1;
}
return(t);
}
function ConnorsRSI(V1, V2, V3)
{
t1 = RSIa(C, V1);
t2 = RSIa(StreakDuration(C), V2);
OneDayReturn = (C - Ref(C, -1)) / Ref(C, -1);
t3 = PercentRank(OneDayReturn, V3);
return ((t1+t2 + t3) / 3);
}
/////////////////////////// Parameters ///////////////////////////
w = Optimize("W", 8, 1, 20, 1); //Percent below previous close
x = Optimize("X", 10, 5, 95, 5); //Position in Range of Close
y = Optimize("Y", 5, 5, 95, 5); //ConnorsRSI for entry
z = Optimize("Z", 10, 0, 16, 1); //Entry limit
n = Optimize("N", 80, 5, 95, 5); //ConnorsRSI for exit
/////////////////////////// Indicators ///////////////////////////
LowBelowClose = Max(100*(Ref(C, -1) - L) / Ref(C, -1), 0);
PIROfClose = 100*(C-L) / (H-L);
LimitEntry = (1-0.01*z) * C;
/////////////////////////// Rules ///////////////////////////
ER1 = ADX(10) > 30;
ER2 = LowBelowClose > w;
ER3 = PIROfClose < x;
ER4 = ConnorsRSI(3, 2, 100) < y;
ER5 = L < Ref(LimitEntry, -1);
XR1 = ConnorsRSI(3, 2, 100) > n;
/////////////////////////// Signals ///////////////////////////
Buy = Ref(ER1, -1) AND Ref(ER2, -1) AND Ref(ER3, -1) AND Ref(Er4, -1) AND ER5;
BuyPrice = Min(O, Ref(LimitEntry, -1));
Sell = XR1;
SellPrice = Close;
/////////////////////////// Plots ///////////////////////////
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
Dual Time Frame
// Dual Time Frame
// Taken or adapted from Mean Reversion Trading Systems by Howard Bandy
//Use RSI on weekly data as a filter. Take positions when RSI on daily data is at a low level
/////////////////////////// System Settings ///////////////////////////
OptimizerSetEngine("cmae");
eq = Param("Fixed Equity", 100000, 1, 10000000);
percentEQ = Param("Percentage of EQ to risk", 1, 0.01, 1, 0.01);
SetOption("ExtraColumnsLocation", 1);
SetOption("CommissionMode", 2); //$ per trade
SetOption("CommissionAmount", 5);
SetOption("InitialEquity", eq);
SetPositionSize(percentEQ*eq, spsValue);
MaxPos = 1;
SetOption("MaxOpenPositions", MaxPos);
SetBacktestMode(backtestRegularRawMulti);
SetTradeDelays(0,0,0,0);
BuyPrice = SellPrice = Close;
/////////////////////////// Parameters ///////////////////////////
DailyRSILB = Optimize("DailyRSILB", 3, 2, 6, 1);
DailyBuyLevel = Optimize("DailyBuyLevel", 15, 5, 30, 1);
WeeklyRSILB = Optimize("WeeklyRSILB", 5, 1, 10, 1);
WeeklyPermitLevel = Optimize("WeeklyPermitLevel", 64, 10, 90, 1);
/////////////////////////// Indicators ///////////////////////////
//The data base is daily
//Form weekly bars
TimeFrameSet(inWeekly);
WRSI = RSI(WeeklyRSILB);
TimeFrameRestore();
//Expand weekly indicator to daily periodicity
WeeklyRSI = TimeFrameExpand(WRSI, inWeekly);
DailyRSI = RSI(DailyRSILB);
//Rules
Permission = WeeklyRSI > WeeklyPermitLevel;
//Signals
Buy = Permission AND DailyRSI < DailyBuyLevel;
Sell = DailyRSI > 75; //Or !Permission
Buy = ExRem(Buy, Sell); //Remove excess signals
Sell = ExRem(Sell, Buy);
/////////////////////////// Plots ///////////////////////////
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
shapes = IIf(Buy, shapeUpArrow, shapeNone);
shapecolors = IIf(Buy, colorGreen, colorWhite);
PlotShapes(shapes, shapecolors);
Plot(WeeklyRSI, "WeeklyRSI", colorGreen, styleDots|styleThick|styleLeftAxisScale);
Plot(DailyRSI, "DailyRSI", colorBlue, styleLine|styleThick, styleLeftAxisScale);
Three Days High Low Long
Entry rules are based on the three days high-low long system from the book “High Probability ETF Trading” by Larry Connors and Cesar Alvarez.
A trade simulator that allows us to test entering the first order, the second order, or both orders.
//SimulateMultiplePositions.afl
// Taken or adapted from Mean Reversion Trading Systems by Howard Bandy
//This program implements the 3 Day High Low system for both basic and aggressive trades.
//It allows either level of trades to be isolated so they can be evaluated independently.
//This is a simplified trading system simulator.
//Data is stored in arrays, one element for each data bar
//Nheld - Number of long positions held
//EntryP1 - Entry price for Position 1
//EntryP2 - Entry Price for Position 2
//Buy1 - Signal to enter the first position
//Buy2 - Signal to enter the second position
//SellAll - Signal to exit all positions
/////////////////////////// System Settings ///////////////////////////
OptimizerSetEngine("cmae");
eq = Param("Fixed Equity", 100000, 1, 10000000);
percentEQ = Param("Percentage of EQ to risk", 10, 1, 100, 1);
SetOption("ExtraColumnsLocation", 1);
SetOption("CommissionMode", 2); //$ per trade
SetOption("CommissionAmount", 5);
SetOption("InitialEquity", eq);
//SetPositionSize(percentEQ*eq, spsValue);
SetPositionSize(percentEQ, spsPercentOfEquity);
MaxPos = 1;
SetOption("MaxOpenPositions", MaxPos);
SetBacktestMode(backtestRegularRawMulti);
SetTradeDelays(0,0,0,0);
BuyPrice = SellPrice = Close;
/////////////////////////// User Functions ///////////////////////////
//Parameters
LongTermMALength = 200;
ShortTermMALength = 5;
ExitMALength = 5;
/////////////////////////// Indicators ///////////////////////////
LongTermMA = MA(C, LongTermMALength);
ShortTermMA = MA(C, ShortTermMALength);
/////////////////////////// Rules ///////////////////////////
//Filter - Close must be above its long term moving average
FilterRule1 = C > LongTermMA;
//Close is below its short term moving average
EntryRule1 = C < ShortTermMA;
//Three days of lower lows and lower highs
EntryRule2 = Ref(H, -2) < Ref(H, -3) AND Ref(H, -1) < Ref(H, -2) AND H < Ref(H, -1) AND
Ref(L, -2) < Ref(L, -3) AND Ref(L, -1) < Ref(L, -2) AND L < Ref(L, -1);
//Clsoe is above its short term moving average
ExitRule1 = C > ShortTermMA;
/////////////////////////// Trading System Simulator Loops ///////////////////////////
//Initialize
Nheld = 0 * Close;
EntryP1 = 0 * Close;
EntryP2 = 0 * Close;
Buy1 = 0 * Close;
Buy2 = 0 * Close;
SellAll = 0 * Close;
// Loop to process all data bars
for (i = 1; i < BarCount; i++)
{
//At the open. No actions at the open.
//Intrabar. No actions intrabar.
//At the close.
if (NHeld[i-1] > 0 && ExitRule1[i])
{
//Process Exits
SellAll[i] = 1;
NHeld[i] = 0;
}else
{
//Process Entries
switch (NHeld[i-1])
{
case 0: //holding none - check for buy
{
if (FilterRule1[i] AND EntryRule1[i] AND EntryRule2[i]) //Entry a long position
{
Buy1[i] = 1;
EntryP1[i] = Close[i];
NHeld[i] = 1;
}else //no action
{
NHeld[i] = 0;
}
break;
}
case 1: //holding one - check for aggressive entry
{
if (Close[i] < EntryP1[i-1]) //Take a second position
{
Buy2[i] = 1;
EntryP2[i] = Close[i];
NHeld[i] = 2;
EntryP1[i] = EntryP1[i-1];
}else //no action
{
NHeld[i] = 1;
EntryP1[i] = EntryP1[i-1];
}
break;
}
case 2: //Holding two - the maximum, no action
{
NHeld[i] = 2;
EntryP1[i] = EntryP1[i-1];
EntryP2[i] = EntryP2[i-1];
break;
}
} //end switch
} //end of else block (process entries)
} //end of for loop
//Pass signals to amibroker for reporting
TestingEntry = 3; // Trades at Level 1 or 2; 3 means both
switch(TestingEntry)
{
case 1:
{
//First buy
Buy = Buy1;
BuyPrice = EntryP1;
Sell = SellAll;
SellPrice = Close;
break;
}
case 2:
{
//Second buy
Buy = Buy2;
BuyPrice = EntryP2;
Sell = SellAll;
SellPrice = Close;
break;
}
case 3:
{
//Take all trades
Buy = Buy1 + Buy2;
BuyPrice = IIf(Buy1, EntryP1, IIf(Buy2, EntryP2, 0));
Sell = SellAll;
SellPrice = Close;
break;
}
} //end switch
/////////////////////////// Plots ///////////////////////////
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
Plot(LongTermMA, "LongTermMA", colorRed, styleLine);
Plot(ShortTermMA, "ShortTermMA", colorGreen, styleLine);
Shapes = IIf(Buy, shapeUpArrow, IIf(Sell, shapeDownArrow, shapeNone));
ShapeColors = IIf(Buy, colorGreen, IIf(Sell, colorRed, colorWhite));
PlotShapes(Shapes, ShapeColors);
Trade SPY from VIX
//TradeSPYFromVIX.afl
// Taken or adapted from Mean Reversion Trading Systems by Howard Bandy
//Using VIX as the source of data for the signals. When VIX is high, buy the surrogate.
//This system uses a 2 period RSI of VIX
/////////////////////////// System Settings ///////////////////////////
OptimizerSetEngine("cmae");
SetOption("InitialEquity", 100000);
MaxPos = 1;
SetOption("MaxOpenPositions", MaxPos);
SetPositionSize(10000, spsValue);
SetOption("ExtraColumnsLocation", 1);
SetTradeDelays(0, 0, 0, 0);
BuyPrice = SellPrice = Close;
/////////////////////////// Parameters ///////////////////////////
RSILB = Optimize("RSILB", 4, 2, 6, 1);
BuyLevel = Optimize("BuyLevel", 83, 1, 99, 1);
SellLevel = Optimize("SellLevel", 9, 1, 99, 1);
ProfitTarget = Optimize("ProfitTarget", 0.5, 0.5, 2, 0.25);
/////////////////////////// Indicators ///////////////////////////
VIXC = Foreign("$VIX", "C");
RSI2 = RSIa(VIXC, RSILB);
Buy = RSI2 > BuyLevel;
Sell = RSI2 < SellLEvel;
ApplyStop(stopTypeProfit, stopModePercent, profitTarget);
How Markets Really Work Sample Strategy (by Larry Connors)
Refer to https://smarttradingstrategies.com/how-markets-really-work-by-larry-connors/#Rules
DayOfTrade = Param("Day of Trade", 5, 1, 5, 1);
BuyPrice = Close;
SellPrice = Close;
//------------------ SYSTEM (Larry Connors How Market Really Works) ----------------------------
// Parameters and Indicators
SetForeign("^GSPC");
SPFilter = C >= MA(C, 200);
RestorePriceArrays();
// Buy Rules
Buy = SPFilter AND C >= MA(C, 200) AND Ref(C, -1) < Ref(O, -1) AND C < O AND RSI(2) < 15 AND StDev(C, 100) < 35 AND DayOfWeek() == DayOfTrade;
Sell = DayOfWeek() == DayOfTrade AND BarsSince(Buy) > 1;
PositionScore = StDev(C, 100);
SetPositionSize(10, spsPercentOfEquity);
SetOption( "MaxOpenPositions", 10);
