Simple Ideas for a Mean Reversion Strategy with Good Results

A reader sent me some trading rules he got from a newsletter from Nick Radge. He wanted to know if these rules really did as well as published in the newsletter. They seemed too simple to produce such good results. This is a basic mean reversion or pullback strategy. The strategy as presented was long and short and went on margin but he wanted to know how it did the long only since he did not short. After contacting Nick Radge at The Chartist, I confirmed with him it was OK to publish these rules.

The Original Rules

Tested from 1/1/1995 to 5/31/2014. Maximum 20 positions at 10% of equity each. This means the strategy can be 200% invested. Rarely did one get 200% invested according to Nick Radge.

Setup

  • Close greater than 100-day moving average
  • Close less than the 5-day moving average
  • 3 lower lows. (Not lower closes, I made this mistake the first time I wrote the code)
  • Member of the Russell 1000

Buy

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

Sell

  • Close is greater than the previous day’s close
  • Sell on the next open

 

Comments on the Rules

No fancy rules are here. It is standard mean reversion strategy. At times the strategy will produce more signals than there are open slots for. To trade this, one must be watching the markets during the day and take the signals as they happen. This is not realistic for most people since they are not full time traders sitting in front of their computers. One could automate this, but that is not a simple task.

You may have taken pause at the very simple exit rule of ‘an up close.’ That rules brings back memories while I was working for Connors Research. The first time I heard about this rule and tested. I thought there is no way this rule could work. I figured it would destroy a perfectly good strategy. I was flabbergasted that it worked and produced good results. This is why I say that one should test ideas before throwing them out. You never know what will work.

The Tested Rules

I made the following changes to original rules.

  • Tested from 1/1/2004 to 6/30/2014
  • Allow max of 10 positions at 10% each. No margin.
  • Added a liquidity rules of:
    • 21-day moving average of dollar-volume greater than $10 million
    • Price as trade greater than 1

When there are more signals than open positions, the code would randomly choose which stocks to enter. I then ran 500 runs for each test.

Russell 1000 Results

140811a

The average CAR of the 500 Monte Carlo runs is 22.35% with a Max DD of 21.02%. Surprisingly good results from such simple rules. The standard deviation for CAR and MDD are much smaller than expected.

S&P 500 Results

140811b

The results are not as good as using the Russell 1000 but still good. Probably because of the smaller universe which leads to lower exposure.

Russell 3000 Results

140811c

Having a larger universe, gives us more exposure which gives higher CAR.

Spreadsheet

If you’re interested in a spreadsheet of the data used to generate these tables, enter your information below, and I will send you a link to the spreadsheet. The spreadsheet includes the full Monte Carlo run data. In the spreadsheet are details on how to obtain the AmiBroker code that I used for this post.

Final Thoughts

What I like about this strategy is how simple it is, yet produces good results. Only 3 set up rules. One really simple exit rule that one would think would not work. The biggest issue with the strategy is that most people cannot trade it because it requires being in front of the market all day long. In a future post, we will look into changes the rules to make it more tradable for the average person.

Backtesting platform used: AmiBroker. Data provider: Norgate Data (referral link)

Added on 8/5/2015: Want to see how a maximum loss stop changes the results, read Maximum Loss Stops: Do you really need them?

 

Added on 8/15/2014: In the comment thread below, a couple of people questioned the results. I had a researcher friend of mine code up the rules as stated on this post. His results matched mine exactly. This gives me complete confidence that the results are correct.

 

Good Quant Trading,

 

Fill in for free spreadsheet:

spreadsheeticon

 
Visited 309 times, 3 visit(s) today

Click Here to Leave a Comment Below

Henjo Jie - August 11, 2014 Reply

Hi Cesar,

I loved your work in TradingMarkets. It is because of you guys that I have started looking into mean reversion strategies for stocks.

With the issue of many signals and watching the screen, Interactive Brokers has Basket Trader facility that allows a trader to enter many market-if-touched orders. Thus, he/she would not need to sit in front of the screen all day as IB will automatically submit the order when the price condition is met. The maximum position that can be opened during the day will then depend on the funding permission the trader has.

A quick question if you don’t mind. I am using Amibroker as well to run monte carlo simulation. However, I cannot produce the YEARLY statistics of returns (average, min, max, median) from Amibroker. Is that a custom backtester? Or do you run it manually for each year?

Thank you for your answer.
Henjo

    Cesar Alvarez - August 11, 2014 Reply

    I am very familiar with basket orders. The question is if one has a margin account but does not want to on margin, how does one do that?

    I used the CBT to output the yearly return for each run. Then I took all the runs pasted them into Excel. From there I generated the statistics.

    Cesar

Chris - August 11, 2014 Reply

I’m surprised this strategy has positive return even in 2008.

    Cesar Alvarez - August 12, 2014 Reply

    2008 tends to be a good year for mean reversion strategies.

      Jane Fox - August 18, 2014 Reply

      I agree Cesar, 2008 was an awesome year for mean reversion.

Ola Hansson - August 11, 2014 Reply

Hi Cesar,

Thanks for the great work!

I’m currently following another of Nick Radge’s strategies from his book Unholy Grails. This is a breakout /trendfollowing strategy. I think that complementing this with a mean reversion strategy would be a good idea.
What you are describing here looks temptingly good. I presume you are not including commission/slippage in the tests? If you are trading in Australia this is an issue unfortunately.

If I understand it correctly you would enter your orders EOD, so there is really no reason to monitor the market during the day, or am I missing something?

Keep up the good work!

Cheers,
Ola

    Cesar Alvarez - August 12, 2014 Reply

    Yes, I do include $.01/share for commission/slippage. See my FAQ, https://alvarezquanttrading.com/faq/, for more details on how I do my tests. The issue is that you may have 40 stocks that set up the night before and you do not know which will trigger. In 30 of those trigger, you only want to get into the first 10 that do.

Pete - August 12, 2014 Reply

Some simple questions:

1) What about turnover of the strategy? Do you use any cost and slippage?
2) Survivorship bias can have a very big impact on performance, probably more then we can imagine. Do you consider it?
3) Which software do you use for backtest?
4) don you know a solution (software + data provider) that made simple backtesting with delisted stocks (eliminate survivorship bias)?

    Cesar Alvarez - August 12, 2014 Reply

    See my FAQ, https://alvarezquanttrading.com/faq/, for more details on how I do my tests. This answers all your questions and then some.
    1 – The turnover is high because of the quick exit. I use $.01/share for commission/slippage.
    2 – No survivorship bias since my data has delisted stocks.
    3 – I use AmiBroker
    4 – I use AmiBroker and Premimum Data for my testing.

Serg - August 12, 2014 Reply

Pls show data for NASDAQ-100 and S&P 100. I get the impression your study involves selection bias, i.e. you only show the good results. I may be wrong but this is what my analysis says.

Also please include data from 05/31/2014 to present where the Russel 2000 has suffered a lot.

More importantly, this is a simple system but has 6 parameters so from the PoV of curve-fitting this is not very simple.

    Cesar Alvarez - August 12, 2014 Reply

    Maybe in a follow up post I will include SP100 & Dasdaq-100. My guess they will not do as well because of lack of exposure. Running a Monte Carlo run takes time. If I do a follow up, I will also include R2000.

    Two of the rules are liquidity rules which the original rule did not have. It is not realistic to test these lower volume stocks. My guess is if I removed these rules results would improve because that has been my experience.

    I disagree that these rules constitute curve fitting. They only a few rules, simple parameters, and each rule makes sense. The issue with when a strategy has crossed from being non-curve-fitted to curve-fitted is that there is a large grey area in between which people have disagreements on when curve-fitting has happened. The good part is that if one thinks curve-fitting has happened, one can ignore the research and not trade.

      Serg - August 12, 2014 Reply

      In the period tested there are about 2,375 bars bit you have 7,183 trades for the Russell 1000. Divide that by 10 and multiply by the average holding period and you get 2,571 bars. This means that many positions overlap and although you open 10 positions at the time max you hold many more open. This is why your CAR is overstated. If you adjust that and you add reasonable slippage you do not even make it near buy and hold with reinvested dividends. Your high CAR is a red flag. Any CAR above 15% is a red flag. Apparently, your backtests are based on using open equity to buy more stock. You cannot do this in real life. You have to add money to the account. When you do that and also account properly for slippages, the method is a loser.

        Cesar Alvarez - August 12, 2014 Reply

        There are 10.5 years in the test with 252 bars per year. That gives 2646 bars in the test not 2375. The average hold is 3.58 bars but one needs to understand how AmiBroker calculates the number of bars held for a position. If I enter a position today at the open and exit tomorrow on the open, AmiBroker calculates that as a 2 bar hold. In reality that is only 1 bar of time. One should subtract one from the ‘Avg Bards Held’ that AmiBroker prrovides.

        If we take (((7183 trades)/(10 positions)) * (3.58-1 bars))/(2646 total bars in test)*100=70% which is very close to the ‘Exposure %’ in the AmiBroker report of 69.67%. By these calculations all is good.

        Because of your concerns, I double checked my code to make sure I was not entering more than 10 positions or using margin. I am always aware that I can (and I do) make mistakes. After checking my code, I see no problems.

          Serg - August 12, 2014 Reply

          Actually it’s more complicated than that and the exposure calculation is wrong because you are doing a long-only system and you have to look only in periods when the conditions are met. Given that, the system is probably holding many more positions than 10 at a given time. Note that most retail backtresters calculate CAR based on starting and initial equity and do not account for margin. The only way for this to be resolved is for you to provide a complete trade-by-trade report here so everyone can be convinced that you are not using margin in your CAR calculations. I thought this is what was included in the spreadsheet but I only found a link there for buying the Amibroker code for $50. If this system was a true winner I doesn’t make sense to sell it for $50, this is what the theory of rational behavior says.

          I am not convinced at all that your results are correct or that your code is correct. The only way for you to convince me is to provide complete results or code so that your readers can reproduce them.

        Cesar Alvarez - August 14, 2014 Reply

        Serg,

        Here is the code that prevents me from having more than 100% invested.
        Here is the code that limits me to not having more than 10 positions or having more than 100% invested. Unless AmiBroker, has suddenly broken, these lines should prevent me from having more than 100% invested.

        posqty = 10;
        pctPerPosition = 100/posqty;
        SetOption(“MarginRequirement”,100);
        SetPositionSize(pctPerPosition,spsPercentOfEquity);

        If you still believe the code is wrong, I suggest that you code up the strategy and post your results. I have given you the full rules. I am hiding nothing. There still may be an error in the code that I have not found, but at this point I leave it to you to code and post results that contradict my results.

        Cesar

          Serg - August 15, 2014 Reply

          I’m only trying to help hear but pls no reversal of burden of proof will be accepted. Which version of AMI do you use?

          Try adding this

          SetOption(“MaxOpenPositions”,10);

          I will repeat again that the high return should have immediately triggered a red flag. Anyone with more than 3 months backtesting experience knows this.

          Cesar Alvarez - August 15, 2014 Reply

          I am doing that. Here is that line of code
          SetOption(“MaxOpenPositions”,posqty);

          Cesar Alvarez - August 15, 2014 Reply

          Because of your continued concerns and that I want to make sure the code is correct (like I have said before it is possible that I have a bug that I have not found), I asked a favor from someone I know who is a professional researcher with very strong AmiBroker skills, to program the strategy as the rules as given in this post. When I worked for Connors Research the way we verified a strategy was by giving the English rules (as in this post) to another researching to code up. We then compared results.

          The researcher’s results for this strategy matched mine identically. At this point, I consider the strategy verified and correct. Unless you want to say the rules as stated in the post are wrong.

Aaron - August 12, 2014 Reply

I would like a copy of the spreadsheet. Thanks.

    Aaron - August 12, 2014 Reply

    Also, as far as the rules go. Does the close below the 5 day MA have to happen first, and then the 3 lower lows after that? Or can the 3 lower lows begin above the MA and then the close below the 5 day MA happens on the 3rd day?

      Cesar Alvarez - August 12, 2014 Reply

      To get a copy of the spreadsheet. Fill out the form at the bottom of the post.

      On the setup day, the close has be under the MA5 and that day is at least the third day in a row of 3 lower lows.

      Cesar

Jim P. - August 13, 2014 Reply

Instead of trading individual stocks, how would your results be different for trading ETF SPY, either Long, Short, or Money mkt, and only at EOD? Thanks for sharing your work. Regards, Jim

    Cesar Alvarez - August 13, 2014 Reply

    One would have to make big changes in the strategy because of lack of trades, the exposure would be very low and thus low CAGR.

Jim P. - August 13, 2014 Reply

Thank you Cesar. That was my suspicion as well, …that there would be very few trades if one were trading SPY. Is there a favorite strategy (of yours, or that you recommend) for trading SPY at EOD only? Thank you.

    Cesar Alvarez - August 14, 2014 Reply

    I currently do not trade the SPYs. I am researching a possible SPY option trading strategy. But that is in the early stages of investigation.

Alex - August 14, 2014 Reply

Hello, what AFL statement are you using to limit open positions to 10. As someone already pointed out it appears you system takes more than 10 positions and exceeds cash equity. I remember AFL has a command to limit the opening of new positions to 10 but i do not recall it having one to limit new positions based on already open ones. As already noted the CAGR is unrealistic and this is possibly due to overestimation.

    Cesar Alvarez - August 14, 2014 Reply

    As I have pointed out, I believe the code is correct. Not to say that it could still be wrong. I have checked it several times. Why do you think the code is wrong?

    Here is the code that limits me to not having more than 10 positions or having more than 100% invested. Unless AmiBroker, has suddenly broken, these lines should prevent me from having more than 100% invested.

    posqty = 10;
    pctPerPosition = 100/posqty;
    SetOption(“MarginRequirement”,100);
    SetPositionSize(pctPerPosition,spsPercentOfEquity);

      Cesar Alvarez - August 15, 2014 Reply

      One more line of code
      SetOption(“MaxOpenPositions”,posqty);

Shawn - August 14, 2014 Reply

Hi Cesar

Thanks for the awesome, interesting site & blog.

With regards to the exit of this system: “Close is greater than the previous day’s close”, how do you exit if this condition never actually occurs? That is, the exit requires a close price greater than the previous day’s close price, so what if the price just kept falling, as an example. Wouldnt you hold it all the way down? Or if the price kept oscillating in a range such that this condition never came true. The stock might be held forever?

What am I missing?

    Cesar Alvarez - August 15, 2014 Reply

    Yes in theory the stock could close down every day until it hit zero. In all my testing this has never happened. If the price oscillates, then we will get out because in order to oscillate the stock must close up and then we would get out. I agree with you it is a strange exit.

Greg - August 15, 2014 Reply

Cesar,
What would be the inverse version of this strategy? (i.e what are the inputs if you wanted to trade short?)

    Cesar Alvarez - August 15, 2014 Reply

    First, I have not tested the short version of this. The inverse rules changes are
    Setup changes would be
    Close < MA100 Three higher highs Close > MA5

    Buy change
    Trigger is Previous close + .5 * ATR10

    Sell change
    Sell on first down close

Serg - August 16, 2014 Reply

Cesar: ” I asked a favor from someone I know who is a professional researcher with very strong AmiBroker skills, to program the strategy as the rules as given in this post.”

I find it interesting that this person was able to program this strategy, generate the results and test them in less than half a day. Originally, when you gave the rules the option I gave you was not included. This is what you gave:

posqty = 10;
pctPerPosition = 100/posqty;
SetOption(“MarginRequirement”,100);
SetPositionSize(pctPerPosition,spsPercentOfEquity);

And this one I suggested

SetOption(“MaxOpenPositions”,posqty);

was not included. Your post that this must be included has a time stamp at least 3 hours after my post. I do not see a reason for omitting it in the first place because it deals with exactly the issues raised.

Therefore, one way for you to prove that your results are correct is to post an excel file of the Amibroker trade-by-trade output for the first case of Russell 1000. I don’t think you should have any objections to that. Then the issue will be settled either way. You may have something here but the odds are against you and you possibly either have optimized the system to fit past data or you have a bug that overstates CAGR. If this system worked and actually produces a CAGR that high it does not make any sense to sell the code for $50. Please do not tell me you are a good Samaritan and you want to make your blog visitors rich for a $50 down.

    Cesar Alvarez - August 16, 2014 Reply

    The reason for the omission is I missed that one line of code when I copied over what I wanted to show. Since you have had someone code it up, you can verify for yourself if the results are correct or not. As far as I am concerned, these results are correct as I stated I had a another person code them up and get exactly the same results. I appreciate you bringing up your concerns that the code was wrong but I have proved to myself there are no issues. I will only spend more time and energy on this topic, if someone brings proof that the results are wrong.

Piotr - August 16, 2014 Reply

This strategy is in fact an intraday strategy, not interday. You might have many stocks that meets the criteria on given day. In real life however, you would only buy these stock, that will go down earlier. Having EOD data you do not really know, which one you will buy. That is why you need to use MonteCarlo

Lets suppose, that on given fay 5 stocks meet criteria and goes down by at least 5 percent. After few days 4 of them reverses (“goog stocks”) and one goes further down (“bad stock”). MonteCarlo assumes that the distribution of probability is uniform. Other words, you will buy good stocks in 4 cases and the bad one in 1 case.

And what if bad stock almost always goes down quicker that good stock? That will mean, that the distribution of probability is not uniform. And the test results are not reliable. My question is: why could you assume that the first stock that will go down is a good stock. How do you know, that the stock that will first go down to limit on given day is not “bad stock”. I am asking the question, because I created similar mean reversion strategy, but this question worries me

    Cesar Alvarez - August 16, 2014 Reply

    I did do a Monte Carlo simulation on these results. We do not know which stocks trigger first. You are correct that we do not know if bad stocks tends to trigger first or not, thus the distribution is not uniform.

AZ Trader - August 16, 2014 Reply

what does the code look like for the following buy rule?:

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

I ask becuase it seems every time I attempt to code a limit order in amibroker I get a Holy Grail outcome!

Thanks.

    Cesar Alvarez - August 16, 2014 Reply

    The reason you end up with a Holy Grail system is that there may be 100 signals and your system like this one, takes those that signal. In most peoples real trading they are not sitting in front of the computer to see which ones trigger first and then entering those. The more likely case is that one places limit orders for the first 10 ranked stocks. But then these may or may not get filled. Thus you end up with a much lower exposure and lower CAGR.

      Piotr - August 18, 2014 Reply

      If you have many signals on one day. instead of placing first say 10, you might place One-Cancel-All.That way you will always buy the stock, that first triggers on the limit. However, you will buy a maximum one stock daily, On the other hand, if you have 100 stocks with signal and if you place orders for 10 of them, you might buy nothing

      Regards

AZ Trader - August 16, 2014 Reply

Also, thanks for sharing this very hard work you have done. It seems no good deed goes unpunished.

Thanks for the great info!

Howard Bandy - August 20, 2014 Reply

Hi Cesar —

Nicely done.

Results improve considerably when the requirement that the price be above its 100 day moving average is removed.

    Cesar Alvarez - August 20, 2014 Reply

    Thank you. I have had several people email about suggestions on how to improve the strategy or make it easier to trade. I will likely do a post on that in the future. I will remember to test by removing the MA100 rule.

Derek - August 21, 2014 Reply

Good work but needs some checking. Would it be possible to provide the Ami backtest report for the S&P 500 case? Thanks

Nick Radge - August 21, 2014 Reply

Cesar,
I ran the data as per your adjustments back to 1995 using delisted and historical constiuents to alleviate survivorship bias (this also offrs some out-of-sample data as your test started 2004). I then ran the same removing the 100-day moving average as per Howard’s suggestion: Results as follows (Original vs Adjusted):

CAGR: 26.6% vs 41.9%
# Trades: 7359 vs 10755
Win%: 64.9% vs 65.2%
maxDD: -14.6% vs -32.8%
W/L: 0.82 vs 0.77

Certainly a significant outperformance, but coming with greater downside. I highly doubt the average trader could handle a 32% drawdown – regardless of the upside. My experience suggests anything over 20% is a struggle.

FWIW, I personally trade a more advanced mean reversion system on and end-of-day basis meaning I don’t need to sit in front of a screen. It can be done.

Thanks for the write-up.

Nick Radge
http://www.thechartist.com.au

    Cesar Alvarez - August 22, 2014 Reply

    Interesting to see these results. I don’t like running test back into the late 90’s because those years tend to have some amazing outsized results. I agree that most people cannot handle drawdowns past 20%. I find even 10% to be tough for a lot of people. I agree it can be done. It just requires some experience on order placement from the user.

Amit Kumar - August 21, 2014 Reply

Based on Nick’s stats, performance increase of 15.3 % is coming at a cost of 18.2 % increase in draw-down. Therefore I would personally not remove the 100 day MAV.

Gary - September 4, 2014 Reply

Cesar,

I feel I am missing the point, but if you start your tests on a given date, why must you run 500 separate tests? Is this because the random parameter leads to different results each time?

Also, how do you run these multiple tests using Amibroker?

Much appreciated
Gary

    Cesar Alvarez - September 4, 2014 Reply

    I use these two lines:
    Optimize(“MC run #”, 1, 1, 500, 1);
    PositionScore = Random();

Simple Ideas for a Mean Reversion Strategy with Good Results – Part 2 » Alvarez Quant Trading - September 8, 2014 Reply

[…] Simple Ideas for a Mean Reversion Strategy with Good Results post generated lots of comments and emails about other ideas to try. This post will cover three of […]

Chris Trader - September 14, 2014 Reply

I backtested this strategy myself, I can comfirm the results above. It seems there is no survivership bias involved as there are good results on random portfolios as well. You can increase the return even more with a same-day-exit on close, althoug that rule makes it even less tradable manually. This strategy needs automatic execute anyway…

Thomas - September 14, 2014 Reply

Hi Cesar,
i could not find any information in your describtion neither in the comments regarding initial stopp loss.
What value did you use for that?

Regards
Thomas

    Cesar Alvarez - September 14, 2014 Reply

    There is no stop loss.

Stephane - September 14, 2014 Reply

HI Cesar,

Thanks for all this great and interesting materials. I am quite new to Amibroker and I just wanted to know what you meant by “3 lower lows. (Not lower closes, I made this mistake the first time I wrote the code)”. Is it 3 LLV in a row? Is it 3 LLV over a certain period? If not on a close, then on what?

Thanks
Stephane

    Cesar Alvarez - September 15, 2014 Reply

    In AmiBroker the code would be “L < Ref(L, -1)" for three bars. One way to code that is LLV(L < Ref(L, -1), 3)

Marco - October 7, 2014 Reply

It’s incredible how mean reverting systems always beat trend forrowing ones… The same I experience with my patterns trading.
https://nightlypatterns.wordpress.com

Friday's Updates & Links – 01.16.15 • How to Beat Wall Street - January 15, 2015 Reply

[…] Simple ideas for a mean reversion strategy. […]

David Ham - January 16, 2015 Reply

I can personally verify that this strategy works in practice. I have been trading a very similar method to this constantly since April 2013. I trade much smaller on each position and trade it globally on Interactive Brokers. My 6 figure (now 7 figure) account is up 75% over that 22 month period. Max drawdown was -8.6% this last October.

My thanks particularly to Cesar as I was a longtime paying student of Connors research and all my methods are based on them.

I built an API to automate the whole process.

    Cesar Alvarez - January 16, 2015 Reply

    David, thank you for the kind words. It is good to hear that your strategy is doing great. Keep at it.

    knatta - March 21, 2015 Reply

    David Ham
    when you say, “built an API to automate the whole process”
    is that in Amibroker ? I use Tradestation so ask

Andy - January 21, 2015 Reply

Do you have a rule of thumb for when it’s best to trade mean reversion and when it’s best to trade trend?

(I know, 64 million dollar question, but there’s got to be a basic, simple rule of thumb.)

Thanks for your fantastic work.

    Cesar Alvarez - January 21, 2015 Reply

    I wish I had simple rule of thumb for that but I don’t. Sorry.

      Dave - February 3, 2015 Reply

      Hi Cesar

      I’ve looked at this before, and will start trading it once I’ve built my current momentum portfolio (based on Nick Radge’s Weekend Trend Trader) up to the level I want.

      I’d just assumed you run both at the same time (momentum/trend and mean reversal) on the understanding that one should be providing returns when the other one isn’t.

      Is that right or too simplistic?

      Regards
      Dave

        Cesar Alvarez - February 3, 2015 Reply

        Dave,

        That is what a lot of people do. I have not found a trend following strategy that I like. I do trade multiple strategies with the same general idea that one is at least working at all times. But remember, when markets go to hell correlation goes to 1.

knatta - March 21, 2015 Reply

Thks Cesar for posting this strategy. I am going to try the same like what Dave said here. test this mean strategy along with a trend following

Ellis - March 25, 2015 Reply

Hi Cesar,

Thanks for a great contribution to mean reversion trading (MRV). I ran across your blog while working my way through Howard Bandy’s book, “Mean Reversion Trading Systems”. This is a very valuable work that I highly recommend.

I am wondering whether MRV works as well with Forex or futures markets. Do you have any experience with this?

Ellis

    Cesar Alvarez - March 25, 2015 Reply

    First let me say I am not a Forex or futures trader. What little testing I have done in these markets, MR seems to work on the futures market and not as much on Forex.

Phil Milsom - March 29, 2015 Reply

I’m very interested in your spreadsheet and the afl code. I have entered my information so you can send me the link to your spreadsheet. to obtain the AmiBroker code that you used for this post.

Kind Regards
Phil.

Ellis - April 6, 2015 Reply

Very interesting thread here. I’ve really enjoyed it.

When I try to put this into Amibroker, my results are similar to what’s posted, but all my trades start with the letter “A”. I think there are so many trades that fit the criteria (3 lowest lows, etc.) that the system just picks out the first 10 stocks.

Is there any way to avoid that?

Thanks,

Ellis

    Cesar Alvarez - April 6, 2015 Reply

    Ellis,

    Assuming you are using AmiBroker what you can do is invest $1000 per position, allow fractional shares and start with $1,000,000 portfolio.

    Cesar

Ed - June 4, 2015 Reply

Cesar,

Did you have the “allow same bar exit” setting checked in Amibroker backtest settings? I got the same good results until I turned same bar exits off.

See symbol CHK on 3 June 2015. With “allow same bar exit” on, the system had a positive return that day. When you look at an intraday chart the sequence of the pricing would make a profitable trade impossible.

My coding could be a little different than yours.

    Cesar Alvarez - June 4, 2015 Reply

    I have SetOption(“AllowSameBarExit”, false); in my code.

Ed - June 4, 2015 Reply

Can you send a copy of your spreadsheet so I can compare?

Thanks.

Mike - June 11, 2015 Reply

Could you please send a copy of the spreadsheet so that I can compare? Thanks.

    Cesar Alvarez - June 11, 2015 Reply

    Fill in the form on the post to get the spreadsheet.

UC - August 4, 2015 Reply

Cesar,

Nice strategy, thanks for backtesting and share the results with us.

Based on my small experience, I guess that what can eventually ruin the party is the slippage.

With M/R strategies on stocks and using IB I either get 10 time your slippage or miss some fills.

Apart of using round lots, based on your vast experience, is there any way to reduce slippage? By mean of chosing right orders and/or routing?

    Cesar Alvarez - August 4, 2015 Reply

    I assume you mean slippage on the exit since entry is a limit entry which you can only have positive slippage. Are you seeing this slippage on low volume high spread stocks? I tend to trade larger stocks. But even there sometimes slippage is an issue. I also use TWAP to get out which avoids some of the issues but then makes it harder to track how your system does in real life since one cannot test a TWAP exit.

UC - August 5, 2015 Reply

I see, TWAP could be go for exits, but not for entries.
Best MR entries occour during shift moves that preceed reversal. In such cases using LIT orders allows me to get all orders executed, but with bad fills. On the other hand, LMT orders allow to have zero slippage, yes, but some of them would not get filled.
What would you consider a decent slippage for a model trading $5-$70 US common stock excahnged 150,000 times a day, on average? Any reccomandation to reduce slippage on entries?
Thank you in advance

    Cesar Alvarez - August 5, 2015 Reply

    I am not sure what I would consider slippage ‘good’ in that range? Part of it depends on how big my edge is vs how much am I willing to give. What I would do is determine you avg % slippage and then use that value for your backtests and see what happens.

IMHO BEST LINKS FROM QUANTOCRACY FOR THE WEEK 3 AUG 15 — 9 AUG 15 | Quantitative Investor Blog - August 6, 2015 Reply

[…] Simple Ideas for a Mean Reversion Strategy with Good Results […]

Maximum Loss Stops: Do you really need them? | Alvarez Quant Trading - August 19, 2015 Reply

[…] will be adding stops to one of the most popular posts, Simple Ideas for a Mean Reversion Strategy with Good Results. I will have to make minor changes to test […]

JMc - September 29, 2015 Reply

Interesting read. I have filled in the form to obtain the spreadsheet.Just wondering if you have the Metastock coding for the system as well? If so are you please able to email to the email address noted. Thanks.

    Cesar Alvarez - September 30, 2015 Reply

    Sorry but I don’t do any Metatstock programming.

kbg - October 6, 2015 Reply

Cesar…it is amazing what one *doesn’t* think of. Thanks for the Positionscore = Random(); tip above. I’ve been leery of limit entry systems due to what was discussed earlier in the thread regarding what candidates may or may not get executed. Running positionscore in AB as random and still seeing good results is a huge confidence booster.

    Cesar Alvarez - October 6, 2015 Reply

    Glad you liked that idea.

Michael - October 23, 2015 Reply

A great system that provides an awesome equity curve with minimal drawdown. However, I can understand the difficulty in practically applying this system. Alvarez, have there been any changes to the rules to make it more tradeable for the average person?

Mohit - November 13, 2015 Reply

After reading your post and reply to many of the queries above, I am highly convinced about your thorough knowledge and skill in amibroker coding.
I am looking forward for your valuable guidance and help in coding the strategy.

God bless
Regards
Mohit

Luis - May 16, 2016 Reply

Hi
Fantastic work, Cesar.
I am using also Premium data, but..

how do you trade only Ruselll 1000 stocks along the years? How do you know which stocks were part of the Rusell 1000 in any specific day?

It seems a very hard work to program..

Thanks

    Cesar Alvarez - May 16, 2016 Reply

    You need to ask to be added to their Alpha program. Then know when a stock is in an index is very easy. A one line function call.
    IsIndexConstituent(“$SPX”);

Stef - September 29, 2016 Reply

Hi Cesar,

Quick question… Is the buy limit order valid for one (next) bar only, or more?

Thank you

    Cesar Alvarez - September 30, 2016 Reply

    It is only for 1 bar(day).

Braulio - October 24, 2016 Reply

Hi Cesar,

I have a few questions:

Do you take positions in non-marginable stocks?
Does your code check for historical margin requirements for each stock?

Regards
Braulio

    Cesar Alvarez - October 24, 2016 Reply

    Yes I do since my data provider does not give me any information if the stock was marginable at that time.

Carlos - November 20, 2016 Reply

Hi César,

I’ve programmed this system in Amibroker but I think it is wrong because of the same bar and symbol signal conflicts. I think that it is difficult for Amibroker to resolve them.

Do you still sell this Amibroker code?

Regards,
Carlos

    Cesar Alvarez - November 20, 2016 Reply

    Yes, I do. Use the contact form if you are interested in it.

Bing - August 16, 2017 Reply

The backtest results as presented are correct – however real life performance when trading the system live will almost invariably result in inferior performance compared to backtest results. The reason is simple — on the occasions whereby there are more trade possibilities than slots – typically the poor quality trades trigger first, leaving a lot of the good stuff on the table.

    Cesar Alvarez - August 17, 2017 Reply

    This is why a tested using a monte carlo approach where if more stocks triggered than I had space for, I then randomly picked which ones I got into which I what I said in the post.

Rakesh - October 24, 2017 Reply

Pleasant technique, a debt of gratitude is in order for backtesting and offer the outcomes with us.

In light of my little experience, I figure that what can in the long run destroy the gathering is the slippage.

Separated of utilizing round parcels, in light of your tremendous experience, is there any approach to diminish slippage? By mean of chosing right requests and additionally steering?

Jerry - November 26, 2017 Reply

Cesar

Thanks for sharing this. I have one question.
The buy is entered if price falls another .5*10ATR. Falls from where? The day’s open, the previous day’s close, the previous day’s low?

    Cesar Alvarez - November 26, 2017 Reply

    From the previous close.

Craig - September 26, 2018 Reply

Hi Cesar

We’ve spoken before about this strategy. Thanks again for sharing!
I implemented 3 different variants of the strategy (the core of the strategy being the single up-day exit) in live since March this year and it has been performing reasonably well. This is on a basket of global stocks (Europe, Japan, Australia) not just US.

What I would say is, good execution from your chosen broker is a key factor for mirroring simulated performance. When I first started using them in live, my live results were systemically worse due to the slippage on non-blue chip stocks, as I was using basic limit orders for entry and market orders for exit.
After switching to an order type called Relative order (on Interactive Brokers), which provides liquidity rather than taking, performance was tying up much better.

In June, I implemented a similar strategy on spot Forex which has similarly produced good results. Have you tested the original strategy on Forex at all?

I’ve observed that these strategies can miss out on some significant gains, when price is still continuing to revert to the ‘mean’, beyond the 1-day up close.
Have you tried testing the strategy with the exit rule modified in the following way:
If current close above entry (trade in profit), an exit will trigger only if there have been (2 or 3)-day up closes (not necessarily consecutive) since entry.
If current close below entry, then exit rule unmodified (i.e. get out fast).

I haven’t tested this yet but I will, and just wondered if you had? 🙂

Thanks
Craig

    Cesar Alvarez - September 26, 2018 Reply

    Yes one needs to be careful with the slippage at the open with smaller stocks. I typically use the IB algos too to get out near the open. My slippage is very small overall. I have not tested on FX markets. Not something that I am interested in trading. Yes, in general I have tested all of those exits but not on this strategy. As to if they work, I really can’t remember. But even if I did, it is best to test ideas on the strategy. Because what did not work elsewhere might work here. Good luck.

Petr Novák - December 14, 2018 Reply

Hello, thanks for this page. Is there code of this strategy for AB (afl)?

    Cesar Alvarez - December 14, 2018 Reply

    Sorry, but I do not supply AmiBroker code.

Leave a Reply: