Better Breakout Trading Model

In this article I will demonstrate a simple breakout strategy for the S&P that utilizes a breakout trading method that has produced consistent results on the S&P E-mini futures market since 1987.

In a recent article entitled, “Better Breakouts In The Electronic Age“, from the October issue of Futures Magazine, author Murray A. Ruggiero, Jr. describes how breakout strategies on the S&P market do not perform so well. It’s been my experience that breakout strategies, such as the common open-range breakout, on the E-mini futures market do not work that great. These types of strategies make use of the market’s 0830 Central open as a key price level to base long and short trades from. An offset value from the open price is calculated and a stop-buy order is placed above the open and a stop-sell order is placed below the open. The market is then free to move in either direction taking you into either a long trade or a short trade. The opposite resting order then acts as your initial stop loss value.

Ruggiero suggests that the electronic age has significantly reduced the open-range breakout strategy’s effectiveness. Why? The once important 0830 Central open of the cash session holds far less importance today as it did in the past because of the nearly 24hr access to the electronic market from any Internet enabled computer. Ruggiero puts it like this…

“The electronic markets have destroyed opening range breakouts for futures markets. Previously, markets were closed for 12 hours or more, whereas now they are closed only for a few hours, if that (30 minutes for E-minis). This has, in turn, made the open ineffective. Although the close is a valuable reference point, it never worked as well as the open, which was a powerful reflection of overnight sentiment shifts because of various reports, such as inflation and unemployment. While the open has lost its significance for commodity futures, stocks still are sensitive to this price point. Although most stocks trade overnight, volume is light and for N.Y. Stock Exchange stocks, we still have a specialist involved in opening the stocks each day.”

While I have no idea if this is the real culprit causing the loss of effectiveness in such trading strategies, breakout strategies on the S&P are difficult beasts to master. In my personal opinion, mean reverting strategies often perform better on the S&P, but let’s look at what Ruggiero has to say.

Ruggiero goes on to develop a test strategy designed to explore the market’s behavior in an attempt to help locate a potential “fix” to the problem of poor performance. I will not get into the details here simply because I would like to focus on Ruggiero’s solution and convert it into TradeStation’s EasyLanguage. However, I will say this: Ruggiero’s experiment was designed to find a better offset or stretch formula and to test what filter might help improve the performance. I found it interesting that attempting to filter trades by volatility did not help. Ruggiero tested taking trades only when the current volatility was rising above an average volatility. You would think this would be a perfect time to take trades, but it wasn’t. In the end, Ruggiero comes up with two very simple rules that produce very interesting results.

The New Offset Formula

The offset is based upon yesterday’s price action. More specifically yesterday’s close, yesterday’s high and yesterday’s low. The formula looks like this:

LowOffset = Absvalue( Close data2 - Low data2 );
HighOffset = Absvalue( Close data2 - High data2);
MaxOffset = Maxlist( LowOffset, HighOffset );
MaxOffsetAvg = Average( MaxOffset, 3 );

In the above code you can see we are using “data2” on many of the price references. In this case, this simply means we are looking at the daily bar chart to get these values. The breakout system we are creating will be trading on a 5-minute chart, but we also wish to reference the daily chart located on data2. We first take the difference between yesterday’s close and the two major price extremes. We then take the larger value of these two values and compute the three-day average. This final value is our offset and is called MaxOffsetAvg in our code.

This MaxOffsetAvg is then applied to the value of yesterday’s close to produce a breakout price where we will place our order to go-long. Below is a code example to place our stop-buy order.

Buy("LE") next bar at Close data2 + MaxOffsetAvg stop;

Momentum Filter

Ruggiero goes on to apply a simple momentum filter to his trades. The momentum calculation is nothing more than the difference between yesterday’s closing price and the average closing price over the past 40 days.

vMomentum  = Close data2 - Average( Close data2, Lookback );

You will notice when the momentum filter is applied, the system will only take long trades when the momentum is negative. In other words, we are looking for falling price action before we place our long orders.

If ( vMomentum < 0 ) And ( EntriesToday(Date) = 0 ) Then Buy("LE") next bar at Close data2 + MaxOffsetAvg stop;

Baseline System

With these simple rules Ruggiero has developed a breakout trading model for the S&P E-mini market. All the following examples are generated from historical price action of the S&P E-mini futures market from 1987 to October 5, 2012. A total of $30 was deducted from each trade to account for slippage and commissions.


The equity graph looks very good considering we are trading a breakout system across the entire lifespan of the S&P E-mini. There are some flat periods during the growth of the curve and there are a few sharp drawdown periods. But also remember we don’t have any stops applied to this system. The entry rules are dynamic, adjusting to the ever changing market volatility. The 40-day lookback period for the momentum filter is not optimized and other values around it also produce positive results. Overall, this baseline system looks very good in my opinion. It’s a promising start to a potential profitable trading model.

Baseline With Offset Stop Loss

The baseline system does not have a stop loss. Let’s add a dynamic stop loss to it. The most obvious stop level is to use our MaxOffsetAvg value. Once a trade is opened, simply place a stop order MaxOffsetAvg distance from our entry. Doing this produces the following results.

 The performance numbers certainly improved. We reduced our drawdown while increasing all other performance measures. Adding a stop clearly improved the system. This got me wondering what would taking half the MaxOffsetAvg value as a stop value look like. I like the idea that a breakout should not retrace much thus, we should only risk half the breakout range.  These results are below.

It looks like we have improved the system again. While the percentage of winning trades has fallen, we reduced our risk, thus improved most of the performance metrics. Overall, this looks promising. Ruggiero has developed a very interesting breakout concept and I thank him for sharing his ideas.

There is so much more that could be tested on this system. What about a regime filter? What about taking short trades by reversing our momentum filter? But this is a fantastic start for a profitable trading system. It looks like we just might have a winner here. I encourage you developers reading this to pursue this concept and share your ideas by leaving a comment below this article.


Better Breakout Strategy ( text file )
Better Breakout Strategy ( TradeStation ELD )
Better Breakout WorkSpace (TradeStation TWS)


10/10/2012 The Expectancy Score values were updated in the above tables due to an error in the calculation.

About the Author Jeff Swanson

Jeff is the founder of System Trader Success - a website and mission to empowering the retail trader with the proper knowledge and tools to become a profitable trader the world of quantitative/automated trading.

follow me on:
  • vimal says:

    Hi Jeff. This is a very good article. I have some thoughts I wanted to share with you/questions:

    1. Does this include/exclude dealing costs and slippage?
    2. What if you adjust the strategy to only trade when the VIX is trading above 15 (I choose 15 arbitrarily but simply trying to exclude low vol periods). At a complete guess, the flat period for trades 150-250 may be during 2004-2006 when Volatility was unusually low
    3. Staying with VIX, a strategy to adjust take profit based on the VIX reading?
    4. What about only taking breakout trades above the 200day MA for longs and shorts below?

    I will stick with the above for now and await your thoughts. Think bringing VIX into the equation may change the shape of the equity curve …..or at least I hope it will.

  • vimal says:

    Hi. Sorry just read the article in more detail and you refer to VIX & Dealing costs/slippage so ignore those points



    • To be honest, I’ve not explored this trading strategy very much. I only recently learned about it and wanted to share it right away since it looks so promising. However, I did test taking trades above a 200 day SMA but this did not help at all. I also tried a 100 and 50 period SMA with no improvement. I also reversed the rules to take short trades. This did not work.

  • vimal says:

    another thought…… days of the week make a difference? Maybe clutching at straws. Or even does calendar month make a difference? I guess calendar month may be curve fitting but days of the week may be more valid.

    Also I presume other timeframes do not work aswell as 5min?

    • These are good questions and ones I can’t answer at this time simply because I have not explored them. If I get some time I would like to test these ideas. I often do not use greater than 5-minute charts for intraday systems simply because backtesting will become less reliable.

  • AnTZ_TK says:

    Hi Jeff,

    I believe your expectancy scores are all wrong due to a formula error: Even though you multiply the expectancy by 365 (CALENDAR days) you then divide by TRADING DAYS (242 p.a. on average) instead of the CALENDAR days of the testing period.

    Example for your best system variation:
    a) what you show above: 0.32 * 377 trades * 365 / (15 years * 242 trading days) = 12.13
    b) correct value: 0.32 * 377 trades * 365 / (15 years * 365 calendar days) = 8.04

    Or is there a reason for multiplying by 365, but then using trading days?


    • Thanks TK. It appears you are correct. I’m looking over the code now and it looks like the trading days value, which appears in the numerator, is incorrect. Again, thanks for taking the time to point this out. I will have to update the values in this article as well as the code which performed the calculation.

  • Hans says:

    Cool thanks man. will take a deeper look into this strategy.

  • John says:

    Hi, I just tried out this strategy as downloaded form your site and for some reason I am not getting the same results at all. I get a very small number of trades over the period (45) and not one single winning trade? Clearly there is a problem somewhere.

    • Hello John – Did you download and use the WorkSpace provided? If not, give that a try and see if your issue is resolved.

  • John says:

    Hi Jeff,

    Yes, imported the workspace and strategy code directly into TS as downloaded from your site without modification. I first had issues with a “MaxBarsBack” error message, but now the workspace loads ok but I get a horrific looking equity curve. The last long entry was 11th March 2009, which is still open. All trades are losing trades, exited by hitting the stop loss.

    I’m just wondering whether there are any settings I should have in TS that I don’t know about to get this working as yours is.

    • John – I just downloaded the WorkSpace from the website to test it, and it appears OK. Within the input of the strategy you will see the “CloseTime” input parameter. This is your local time at which all open trades are closed. This time might need to be adjusted by your local time zone. Give that a try.

  • Mark says:

    Hi Jeff, very interesting article.
    How do you calculate the exit price? Is the close price of that day?. Thank you

    • Mark, the open price of the 5-minute bar after 1500 central is the exit price.

  • Ben says:

    I had the same problem John was having, so I created a ES pit session time that goes from 9:30-4:10 est, I also changed the code on the exit stop from-
    If ( Time = CloseTime ) Then sell next bar at market;


    and I finally got it to work after that, just an fyi for anyone that was having issues, not sure why or how that fixed it but thats what worked for me

  • kristian says:

    Thanks for sharing! However I wonder why you put in a buy stop order instead of a buy limit order? And in your comments you mention that backtesting on TFs bigger than 5m is less reliable, why is that?

    • Hello Kristian. You’re welcome. I have a preference for market orders when backtesting. They tend to be more reliable than limit orders. You most certainly could use a limit orders, if you wish. Reviewing my comment from 2012, I wonder myself what I was talking about. I’m not sure what my intent was. Backtesting on 2, 5 or 10 minute bars should be equally reliable. Sorry for the confusion.

  • Kevin says:

    Hi Jeff
    This looks like a very interesting system and I’m in the midst of working with it. Just one comment/request – for those of us that do not use TradeStation (I use MultiCharts), it would be helpful to have an excel dump of the entire settings and results. I know MultiCharts has a feature where you can export the entire thing to excel. If TradeStation has this ability, it would be a nice reference so that we could see all your assumptions.

    • Thanks for the idea kevin. I’ll keep that in mind.

      • Pablo says:


        I am a MC user as well and just starting to go down this road of developing code for ORB. Shoot me an email if you are interested in collaborating;

  • Ryan says:

    Factoring in slippage & commission, the above has not held up well during since 2012. Comments?

  • Luca says:

    This system works very well, but the futures for many people is too expensive.
    I’m trying to modify the code to use this system with 3 data:
    SPY ETF 5min DATA1
    ES 5 min DATA2
    ES daily DATA3

    Input: {————————————————————————————-}

    MaxOffset(0, data3);

    {== START OF MAIN PROGRAM =====================================================================}

    vMomentum = Close data3 – Average( Close data3, Lookback );
    LowOffset = Absvalue( Close data3 – Low data3 );
    HighOffset = Absvalue( Close data3 – High data3);
    MaxOffset = Maxlist( LowOffset, HighOffset );
    MaxOffsetAvg = Average( MaxOffset, 3 );

    If ( vMomentum OpenTime) and (Time (Close data3 + MaxOffsetAvg) Then Begin

    Buy(“LE”) next bar at Open;


    If ( Time = CloseTime ) Then sell next bar at market;

    //Setstoploss( MaxOffsetAvg/2 * Bigpointvalue );

    • You might find it easier to simply use two data streams. Data1 is the 5-minute SPY and Data2 the daily SPY. As for being expensive, I would think the ETF would be more expensive given the number of shares you may need to trade to get the same dollar return on futures. But I’m biased towards futures.

  • >