Australian (ASX) Stock Market Forum

Why isn't everyone rich trading these systems?

A mean reversion system tested on Norgate Premium Data's 496 stock list of ASX. Date range 1/1/1999 through 6/15/2016. 17.5 years (which is way too long to expect the same system to work without adjustment)
The code was recovered from a directory that was left untouched for two years.
Profitable on 407, not profitable on 89, traded individually.
Allowing all trades on all stocks, there are 141675 trades -- a little more than one trade per stock per month.
83% are profitable.
Average gain per trade is 0.40%.
Average holding period is 3 days.


View attachment 67112

The AmiBroker code

// BuyAfterAnNDaySequenceMultiPosition.afl
//
// This is a modificatiion of Listing 3.2
// BuyAfterAnNDaySequenceMultiPosition.afl
// contained in the book
// "Mean Reversion Trading Systems"
// which is copyright © 2013 Blue Owl Press, Inc
//
// The author of the book and programmer
// of the code is Dr. Howard B. Bandy.
//
// Please read and understand the disclaimer
// associated with all materials related to the book.
//
// To obtain a copy of the book,
// visit the book's website:
// www.MeanReversionTradingSystems.com
//
// This code is provided for the convenience of
// readers of the book.
// Please respect the copyright.
// Do not post this listing without
// the express written consent of Dr. Bandy
//
SetOption( "ExtraColumnsLocation", 1 );
SetOption ( "CommissionMode", 2 ); // $ per trade
SetOption( "CommissionAmount", 0 );
SetOption( "InitialEquity", 1000000 );
SetPositionSize( 10000, spsValue );
MaxPos = 500;
SetOption( "MaxOpenPositions", MaxPos );
//SetBacktestMode( backtestRegularRawMulti );
SetBacktestMode( backtestRegular );
SetTradeDelays( 0, 0, 0, 0 );
BuyPrice = Close;
SellPrice = Close;
// ObFn == K-ratio, CAR/MDD, expectancy

// Define a day as rising based on the closing price
Rising = C > Ref( C, -1 );
Falling = C < Ref( C, -1 );

// The number of days in the sequence
N = Optimize( "N", 2, 1, 7, 1 );

// Direction. 1 == Rising, 0 == Falling
Direction = 0; // Optimize( "Direction", 0, 0, 1, 1 );

// Exit variables
// Maximum holding period
HoldDays = Optimize( "HoldDays", 7, 1, 7, 1 );
// Profit target
ProfitTarget = Optimize( "ProfitTarget", 1.0, 0.2, 4, 0.2 );

// Detect an N day sequence

if ( Direction == 1 )
{
NDaySequence = Sum( Rising, N ) >= N;
}
else
{
NDaySequence = Sum( Falling, N ) >= N;
}

Buy = NDaySequence;

Sell = 0;

ApplyStop( stopTypeProfit, stopModePercent, ProfitTarget );
ApplyStop( stopTypeNBar, stopModeBars, HoldDays );

// Plots
Plot( C, "C", colorBlack, styleCandle );
shapes = IIf( Buy, shapeUpArrow, shapeNone );
shapecolors = IIf( Buy, colorGreen, colorWhite );
PlotShapes( shapes, shapecolors );

/////////////// end /////////////////

Best,
Howard

Off topic, but thought I'd let you know your website isn't working Howard. Any of them(Blue Owl Press either).
 
And Howard,I have been on this site for a while now: your inputs are always extremely sharp and instructive;
Whether I follow TA or not is irrelevant: I want to convey my gratitude/thanks to you and i suspect I am not the only one to feel that way.
Tech/a, DeepState,Smurf1976 and in the past Julia have influenced part of my thinking.Thanks all
End of the warm feeling post, now i can go back raving against the latest PC views, migration issues, etc
 
This Mean Reversion system is simple and the results shown are quite good but I can't get a positive result for Ausralian stocks. I realise the test is done on American stocks but really, the rules are so basic it should be at least up on other stock markets. No stop loss so I used percentage 10. Fills are better assumed to happen at Open or Close price rather than a nominal limit order at 0.5 * ATR() so I left that out. ;)

http://alvarezquanttrading.com/2014...-a-mean-reversion-strategy-with-good-results/

Any thoughts on what was done to rate this 3 bars lower strategy so high?

Code:
PositionSize = -100/10; 
PositionScore = mtRandom();

SetTradeDelays(1,1,1,1); 

Turnover = MA(C * V, 10) > 5000000;

BuyRule1 = C > MA(C, 100);
BuyRule2 = C < MA(C, 5);
BuyRule3 = Sum(L < Ref(L, -1), 3) == 3;

SellRule = C > Ref(C, -1);

Buy = BuyRule1 & BuyRule2 & BuyRule3 & Turnover;
Sell = SellRule;

ApplyStop(0, 1, 10, 2);

Radge first wrote about this system.

Using the LMT order will be better to increase the ave win size and you dont need the stop.

When wrote properly it works well in both markets
 
Radge first wrote about this system.

Using the LMT order will be better to increase the ave win size and you dont need the stop.

When wrote properly it works well in both markets
You don't know what proper is?
 
A mean reversion system tested on Norgate Premium Data's 496 stock list of ASX. Date range 1/1/1999 through 6/15/2016. 17.5 years (which is way too long to expect the same system to work without adjustment)
The code was recovered from a directory that was left untouched for two years.
Profitable on 407, not profitable on 89, traded individually.
Allowing all trades on all stocks, there are 141675 trades -- a little more than one trade per stock per month.
83% are profitable.
Average gain per trade is 0.40%.
Average holding period is 3 days.


View attachment 67112

The AmiBroker code

// BuyAfterAnNDaySequenceMultiPosition.afl
//
// This is a modificatiion of Listing 3.2
// BuyAfterAnNDaySequenceMultiPosition.afl
// contained in the book
// "Mean Reversion Trading Systems"
// which is copyright © 2013 Blue Owl Press, Inc
//
// The author of the book and programmer
// of the code is Dr. Howard B. Bandy.
//
// Please read and understand the disclaimer
// associated with all materials related to the book.
//
// To obtain a copy of the book,
// visit the book's website:
// www.MeanReversionTradingSystems.com
//
// This code is provided for the convenience of
// readers of the book.
// Please respect the copyright.
// Do not post this listing without
// the express written consent of Dr. Bandy
//
SetOption( "ExtraColumnsLocation", 1 );
SetOption ( "CommissionMode", 2 ); // $ per trade
SetOption( "CommissionAmount", 0 );
SetOption( "InitialEquity", 1000000 );
SetPositionSize( 10000, spsValue );
MaxPos = 500;
SetOption( "MaxOpenPositions", MaxPos );
//SetBacktestMode( backtestRegularRawMulti );
SetBacktestMode( backtestRegular );
SetTradeDelays( 0, 0, 0, 0 );
BuyPrice = Close;
SellPrice = Close;
// ObFn == K-ratio, CAR/MDD, expectancy

// Define a day as rising based on the closing price
Rising = C > Ref( C, -1 );
Falling = C < Ref( C, -1 );

// The number of days in the sequence
N = Optimize( "N", 2, 1, 7, 1 );

// Direction. 1 == Rising, 0 == Falling
Direction = 0; // Optimize( "Direction", 0, 0, 1, 1 );

// Exit variables
// Maximum holding period
HoldDays = Optimize( "HoldDays", 7, 1, 7, 1 );
// Profit target
ProfitTarget = Optimize( "ProfitTarget", 1.0, 0.2, 4, 0.2 );

// Detect an N day sequence

if ( Direction == 1 )
{
NDaySequence = Sum( Rising, N ) >= N;
}
else
{
NDaySequence = Sum( Falling, N ) >= N;
}

Buy = NDaySequence;

Sell = 0;

ApplyStop( stopTypeProfit, stopModePercent, ProfitTarget );
ApplyStop( stopTypeNBar, stopModeBars, HoldDays );

// Plots
Plot( C, "C", colorBlack, styleCandle );
shapes = IIf( Buy, shapeUpArrow, shapeNone );
shapecolors = IIf( Buy, colorGreen, colorWhite );
PlotShapes( shapes, shapecolors );

/////////////// end /////////////////

Best,
Howard

Howard this uses 500 positions with a $1,000,000 account, i dont think that is very practical in the real world. Is that right?
 
Yeah thats it, but yours was different too that.. code in the lmt order and it will help and remove the stop
Done it before my first post. The original code (without the stop loss & including the limit order) results 01/2015 to 01/2016 on XKO ...

Untitled.png
 
I see a couple of issues with the MR code, if anyone is attempting it on ASX. Howard himself will be well aware of these, but just saying...

1- commissions for most Aussies will be around .1%
2- Excess signals (Exrem) not included in the code.
3- I like to have 'SetStopPrecedence'
 
I see a couple of issues with the code above.

1- commissions for most Aussies will be around .1%
2- Excess signals (Exrem) not included in the code.

1) That's it! Just had to trick the thing. Thanks for pointing it out. I lowered brokerage and get a positive result. I always test with higher brokerage to compensate for getting in at the "assumed" price in test phase.
2) Exrem makes very little difference. Random or rank/score is another discussion worth having.

As Alvarez noted, one would have to be on screen or alerted when price went to 0.5 * atr below yesty close. It is the limit order that doesn't back test true in my opinion as it buys the low often and we know that isn't possible.
 
Didn't see that sorry, how about over a longer term?
I don't have a delisted stock list so as is I am testing on stocks that were not in present day XKO back in Jan. 2015. The further back the start date the greater the survivorship bias.
 
1) That's it! Just had to trick the thing. Thanks for pointing it out. I lowered brokerage and get a positive result. I always test with higher brokerage to compensate for getting in at the "assumed" price in test phase.
2) Exrem makes very little difference. Random or rank/score is another discussion worth having.

As Alvarez noted, one would have to be on screen or alerted when price went to 0.5 * atr below yesty close. It is the limit order that doesn't back test true in my opinion.

It can be coded accurately and correctly. I trade a similar system and Limit orders are accurate when comparing backtests to trades.

If you have high brokerage it will kill a system like this too. A problem in aus
 
Okay so this needs to be forward tested under present time trading conditions to see if the actual price and quantity desired is achievable.

Code:
// 3 Lower Lows similar to N. Radge rules

SetOption("InitialEquity", 50000);  
SetOption("AllowSameBarExit", 0);   // Sell not on buy bar 
SetOption("UsePrevBarEquityForPosSizing", 1); 
SetOption("AllowPositionShrinking", 1);
SetOption("MinPosValue", 4000);    // 4k minimum trade or no trade taken
SetOption("CommissionMode", 2);    // Dollar amount commission mode
SetOption("CommissionAmount", 20); // Commsec is $19.95 under 10k trade

SetTradeDelays(1,1,1,1); // Buy next bar at buy price set below. Sell next bar

PositionSize = -100/10; 
PositionScore = mtRandom();

Turnover = MA(C * V, 21) > 5000000;

BuyRule1 = C > MA(C, 100);
BuyRule2 = C < MA(C, 5);
BuyRule3 = Sum(L < Ref(L, -1), 3) == 3;

SellRule = C > Ref(C, -1);

Buy = BuyRule1 & BuyRule2 & BuyRule3 & Turnover;
BuyPrice = C - (ATR(10) * 0.5);
Sell = SellRule;

Buy = ExRem(Buy, Sell);
Sell = ExRem(Sell, Buy); 

Filter = Buy OR Sell;

AddColumn(IIf(Buy, C - (ATR(10) * 0.50), Null), "Buy", 1.3, colorBlue);
AddColumn(IIf(Sell, C, Null), "Sell", 1.3, colorDarkRed);
 
Okay so this needs to be forward tested under present time trading conditions to see if the actual price and quantity desired is achievable.

Code:
// 3 Lower Lows similar to N. Radge rules

SetOption("InitialEquity", 50000);  
SetOption("AllowSameBarExit", 0);   // Sell not on buy bar 
SetOption("UsePrevBarEquityForPosSizing", 1); 
SetOption("AllowPositionShrinking", 1);
SetOption("MinPosValue", 4000);    // 4k minimum trade or no trade taken
SetOption("CommissionMode", 2);    // Dollar amount commission mode
SetOption("CommissionAmount", 20); // Commsec is $19.95 under 10k trade

SetTradeDelays(1,1,1,1); // Buy next bar at buy price set below. Sell next bar

PositionSize = -100/10; 
PositionScore = mtRandom();

Turnover = MA(C * V, 21) > 5000000;

BuyRule1 = C > MA(C, 100);
BuyRule2 = C < MA(C, 5);
BuyRule3 = Sum(L < Ref(L, -1), 3) == 3;

SellRule = C > Ref(C, -1);

Buy = BuyRule1 & BuyRule2 & BuyRule3 & Turnover;
[COLOR="#FF0000"]BuyPrice = C - (ATR(10) * 0.5);
[/COLOR]Sell = SellRule;

Buy = ExRem(Buy, Sell);
Sell = ExRem(Sell, Buy); 

Filter = Buy OR Sell;

AddColumn(IIf(Buy, C - (ATR(10) * 0.50), Null), "Buy", 1.3, colorBlue);
AddColumn(IIf(Sell, C, Null), "Sell", 1.3, colorDarkRed);

Interesting!

I asked you a question back at post #38 of this thread and your response in post #39 was "Tried that and buying the low of the day doesn't produce a positive result"

Did you even check the Entry code to see whether it differed from yours?

Obviously not as your "BuyPrice" code is still wrong!

If you want to monitor the system going forward at least use the correct code for the "BuyPrice".

Whilst I might not have the correct code for AmiBroker you should be able to work it out from the code below.

Alter the "SetTradeDelays" Buy to 0 (zero) and change the code to reflect the following

BuyPrice = Min(O,Ref(C-ATR(10)*0.5,-1));

Cheers,
Rob
 
Interesting!

I asked you a question back at post #38 of this thread and your response in post #39 was "Tried that and buying the low of the day doesn't produce a positive result"

Did you even check the Entry code to see whether it differed from yours?

Obviously not as your "BuyPrice" code is still wrong!

If you want to monitor the system going forward at least use the correct code for the "BuyPrice".

Whilst I might not have the correct code for AmiBroker you should be able to work it out from the code below.

Alter the "SetTradeDelays" Buy to 0 (zero) and change the code to reflect the following

BuyPrice = Min(O,Ref(C-ATR(10)*0.5,-1));

Cheers,
Rob

Here is the quote of the entry rule ...

Buy

Set a limit buy order for the next day if price falls another .5 times 10-day average true range.

If price falls another .5 * atr(10). It has to be after the signal bar of three lower lows.
 
Here is the quote of the entry rule ...

If price falls another .5 * atr(10). It has to be after the signal bar of three lower lows.

Correct!

As per your code:-

BuyRule1 = C > MA(C, 100);
BuyRule2 = C < MA(C, 5);
BuyRule3 = Sum(L < Ref(L, -1), 3) == 3;

So Buy on the next bar after the above 3 Buy rules are met on the proviso that
the price on entry has fallen a further ATR(10) from the previous days closing price.

Providing "SetTradeDelays" for the Buy is set to zero bars delay then this code reflects the system rule:-

BuyPrice = Min(O,Ref(C-ATR(10)*0.5,-1));

Ask someone else if you don't believe me however, trust me Wysiwyg when I say I'm only trying to help as you are the one that will benefit from the exercise.

Cheers,
Rob
 
I am going to post one buy/sell trade for the following stocks that met the simple system rules. Limit order buy only.

1. TWE = buy price $9.735
2. STO = buy price $4.16
3. PRY = buy price $3.64
4. MIN = buy price $8.135
5. LNK = buy price $8.14
6. CAR = buy price $12.11
7. BPT = buy price $0.62
 
Top