November 17

38 comments

Improving The Simple Gap Strategy, Part 1

By Jeff Swanson

November 17, 2014

automated trading, Automated Trading Development, EasyLanguage, ES, gap fade, gap strategy

Let’s try to improve upon the gap strategy that was provided by Ben Little’s article entitled, “Testing A Simple Gap Strategy.” In this article Ben demonstrated a simple trading model called, Gap Fade 31, based on the opening gap in the S&P futures market. This was the first gap based article on System Trader Success and it drew a fair amount of attention. Personally, I’ve not looked at gap strategies since 2008. I never did find a gap strategy that I liked. However, I thought this would be a good time to review some concepts I’ve not reviewed in many years.

Gap Fade #1 Trading Model

This trading model opened positions in the opposite direction of a gap. Thus, up-gaps were faded by going short and down-gaps were opportunities to go long. A hard stop value and profit target were placed after a new position was opened. For a more complete description please see the original article.

The trading model utilized two important filters.

  1. A market regime filter which divided the market into Bull or Bear. This was accomplished with a 100-period moving average applied to the daily data.
  2. Range filter which limited to taking trades only if today’s opening price was contained within the previous day’s range. That is, if today’s opening price was above yesterday’s intraday high or low, the trade was not taken.

Ben tested the validity of the regime filter in the original article. By the term “validity” I’m referring to the regime filter to provide value. Clearly the regime filter provided value by reducing unproductive trades and dramatically improved results as seen in the original article. The regime filter forces the trading model to take long trades only taken during a bull regime and short trades only taken during bear regimes. This makes logical sense and helps give credence to the model. Ben also tested the robustness of the regime filter which held up well.

Testing Environment

Because I plan on running some tests I’m going to break my historical data into two portions. An in-sample portion and out-of-sample portion. Thus, when I’m finished with my back-testing I’ll have a portion of the data to test the modified trading model on.

Before getting into the details of the results, let me say this: all the tests within this article are going to use the following assumptions:

  • Starting account size of $100,000
  • In-sample dates are from 1998 through December 31, 2012
  • One contract was traded per signal
  • The P&L is not accumulated
  • $20 was deducted per round trip for slippage and commissions

Baseline Results

Based upon our assumptions above, here is the baseline performance of the trading model. I’ve also attached the TradeStation performance report: Gap_Strategy_Baselin.xls.

Gap Fade #1

Baseline

Net Profit

$24,118

Profit Factor

1.2

Total Trades

1,118

% Winners

72%

Avg.Trade Net Profit

$20.42

Annual Rate of Return

1.44%

Max Drawdown (intraday)

5.2%

Testing the Importance of the Range Filter

I would like to test the validity of the range filter. So, in the test below I simply removed the range filter allowing the trading model to take trades that were outside of the previous day’s range.

Gap Fade #1 No Range Check

Baseline

No Range Check

Net Profit

$24,118

$4,220

Profit Factor

1.2

1.02

Total Trades

1,118

1,674

% Winners

72%

70%

Avg.Trade Net Profit

$20.42

$2.52

Annual Rate of Return

1.44%

0.28%

Max Drawdown (intraday)

5.2%

9.82%

Here we clearly see that avoiding trades that fall outside of the previous day range improves the results. The range check is valid.

Testing Day-of-the-Week Filter

Back in 2008 when I was looking at gap-based trading models, testing day-of-the-week filters was common practice. I remember it was often demonstrated that particular days of the week should be avoided as they continually produced negative results. Let’s see how that looks today with this model.

In this bar graph the x-axis represents the day of the week and the y-axis is the net profit accumulated for taking all trades during that particular day of the week. The first bar is Monday (1), and the last bar (5) is Friday. We can see that Monday and Friday have not produced very good results overall. Not taking gap trade on these days may be a good idea.

The code for this strategy is at the bottom of this article.

Testing Gap Size vs. Profitability

I distinctly remember that the size of a gap also played a roll in determining if a particular trade would be ignored or not. I don’t recall completely, but I think too large of gaps or too small of gaps were avoided. Let’s see what we have going for us today.

I’ve modified the code to take two inputs:

  1. Gap Increments
  2. Gap Iterations

Gap Increments tells the software the size range of gaps that we will be trading. For example, a gap increment of 5 states we are testing gaps that fall within a 5-point range.

Iterations tell the software how many different scenarios we are testing. It is this input value where we use TradeStation’s optimization feature to perform iterations over the trading model while testing different gaps sizes. Based on how the software works, it’s important to start this input value from zero. For example, if we want to perform 6 iterations we would enter zero here and then use the optimizer to test from 0-5. That means we will be performing 6 tests with a gap increment of five. This would generate the following tests:

Iteration

Gap Tested

0

0-5 pts

1

5-10 pts

2

10-15 pts

3

15-20 pts

4

20-25 pts

5

25-30 pts

So in the above example we would have 6 different tests. The first test would only trade gaps greater than 0 and less than or equal to 5 points. The second test would only trade gaps greater than 5 and less than or equal to 10 points. And so on…

Here are the results when I tested the trading model with a gap increment of 1 with 25 iterations.

Looking at this bar graph we can see gaps sizes, at bar #8 is the last bar to produce profits. Bars to the right of #8 produce no profits. Bar #8 represents gaps less than or equal to 9 points and greater than 8 points. In the end it looks like we can improve the system by only taking gaps that are equal to or less than 9 points.

The code for this strategy is at the bottom of this article.

Gap Fade #1 Model With Day-of-Week Filter

Let’s now take what we learned and apply it to our baseline system. First, we apply the day-of-the-week filter (DOW) to our baseline system.

Gap Fade #1 Day-of-Week Filter

Baseline

DOW Filter

Net Profit

$24,118

$27,103

Profit Factor

1.2

1.39

Total Trades

1,118

743

% Winners

72%

75%

Avg.Trade Net Profit

$20.42

$36.48

Annual Rate of Return

1.44%

1.60%

Max Drawdown (intraday)

5.2%

2.87%

Gap Fade #1 Model With Gap Size Filter

Here we apply the gap size filter to our baseline system.

Gap Fade #1 Gap Size Filter

Baseline

Size Filter

Net Profit

$24,118

$28,863

Profit Factor

1.2

1.27

Total Trades

1,118

1,095

% Winners

72%

73%

Avg.Trade Net Profit

$20.42

$26.36

Annual Rate of Return

1.44%

1.69%

Max Drawdown (intraday)

5.2%

4.34%

Gap Fade #1 Model Combining Both Filters

In this test I combined the day-of-week filter with the gap size filter.

Gap Fade #1 Combined Filters

Baseline

Combined

Net Profit

$24,118

$27,138

Profit Factor

1.2

1.43

Total Trades

1,118

690

% Winners

72%

75%

Avg.Trade Net Profit

$20.42

$39.33

Annual Rate of Return

1.44%

1.60%

Max Drawdown (intraday)

5.2%

2.52%

Conclusion

At this point I like the day-of-week filter better than the gap size filter. I like the fact that the net profit per trade and profit factor is larger than the gap size filter. Furthermore, we already have a gap size filter in place with our range check. Thus, I really don’t feel too comfortable adding an additional check on the gap size.

After coming up with these two filters and testing them on our in-sample data, we can now apply them to our out-of-sample data. For now however, I'll be doing this next time as this article is getting a bit long. Once we test our idea on the out-of-sample data we’ll see if our efforts paid off or if it’s back to the baseline system to try new ideas.

Other Article In This Series

Jeff Swanson

About the author

Jeff has built and traded automated trading systems for the futures markets since 2008. He is the creator of the online courses System Development Master Class and Alpha Compass. Jeff is also the founder of EasyLanguage Mastery - a website and mission to empower the EasyLanguage trader with the proper knowledge and tools to become a profitable trader.

        • Results are too important to neglect. How you chose to assess them is subjective. Sharpe, Sortino, CAR/MDD, RAR/MDD etc. Take your pick, we are all free to chose. I think that also applies to Jeff….

          • I remember the story of a guy who worked for a fund and one day he told his boss that he did not like the Sharpe ratio. Security came and kicked out of the building along with his things and a pink slip.

            Do you understand that Sharpe ratio is like a signal to noise ratio? Do you understand that statistical significance of an algo is tight directly to Sharpe ratio? Do you understand that those who do not report Sharpe ratio values have at times something to hide?

          • If I can jump in to this…the Sharpe ratio is available. Simply download the code and execute it on your platform. This trading model is open source so there is nothing to hide. For me, Sharpe ratio at this stage in the development process is not needed. Particularly, when the trading model is not even tested on OOS data yet. But that’s just my opinion.

  • Can you provide a download of the txt version of the code? I have been interested in testing variations on a gap-fill strategy for some time, and unfortunately I can never open your .eld files and need .txt since I use Multicharts instead of Tradestation.

    I really appreciate your articles and the generosity of you sharing your work with others.

    • Hey Paul. Glad you are liking the articles. There are two text files available in the download section of the article. They are the gap strategy code with the two different filters. You can strip out the filters have just the baseline system. Does this help?

  • Thanks for your work Ben,

    my idea in testing long and short trades was mainly referred to the “long bias” that the stock market has, especially in some days of the week. So it would be interesting to know (I can’t do that because i don’t have tradestation available) how the winning percentage of both long and short trades work out during the days of the week. Maybe we could find some interesting ideas.

    Thank you

    Enrico

  • I’d be cautious with drawing too many conclusions from a day-of-week filter. When you segregate the trades by day-of-week, you end up with a relatively small sample size for each day, so your day-by-day results might not be entirely reliable.

    For what it’s worth, I tested your strategy on MultiCharts. I only have access to minute data from September 2006 to the present. However, within this sample, I ended up with completely different results — Monday was OK (profit factor of 1.42), and Wednesday was a stinker (PF of 1.11). None of the days were unprofitable, though.

    Also, as a coding suggestion, it might be easier to encode the DayToTest input as a numeric variable. I.e., Monday = 1, Tuesday = 2, etc. Then, you can simplify your code through something like:

    ValidGapDay = (DayOfWeek(Date) = DayToTest);

    That way, your code would be shorter, and you could also run an optimization on the input from 1 to 5 to get all of the results in one pass.

    • One other thought — as you and Ben noted, the strategy didn’t perform very well in the late 1990’s and early 2000’s. Is it possible that this is attributable to the switchover from pit trading to electronic trading? Perhaps this strategy didn’t work as well back in the pit days.

      (I’m not sure when the majority of the volume switched from pit to electronic — if someone has that information, that would be good to know.)

      • That could be part of the reason for sure. Around the year 2000 or just after, there did seem to be a major shift in the markets. Some would say since 2008, a new shift has taken hold as futures volume has fallen dramatically in a world of zero interest and high frequency trading.

    • I agree. The main reason for this is I can’t think of a reasonable reason on why a particular day should or should not work. I feel much better when I apply a particular filter that as a logical reasons on why it should work. But this one, I can’t think of one. Nonetheless, I included this as I remember day-of-the-week was a filter often discussed. Thanks for the code suggestion.

  • I am quite curios to know if the performance of the short trades is similar to the long ones.
    It is the historical up bias of the stock market which makes me think.

  • Are there any changes in the overall performance about opening a position exactly at the opening at 8.30 or at 8.31 one minute later?

  • How much interesting are the ‘unbalanced’ results in the ’25 and ’29 tests regarding long and short results. Food for thought.

  • I don’t know if you get my last post, but it is very interesting to notice how the long trades performance changes as we change the time of opening the position.

  • Glad to find your website.

    1. I open the TS workspace but it shows :
    “Unable to allocate memory for large data request, reduce
    the range of dat being requested.”

    2. No trade result find in :
    Strategy With Day-of-Week Filter
    Strategy With Gap Size Filter

    I don’t know what is wrong ?

    • There is a lot of historical market data being used. Your error may be happening due to a problem related to available computer resources (memory). Reboot your computer and give it a try again. If that does not work, you may want to limit the historical data to only 5 years or so.

  • Hi Jeff,
    Thanks a lot for sharing your work. I really enjoy reading all your articles.
    Regarding day-of-the-week filter, I found 2 similar references which also show Monday and Friday are less favorable for fading the gap.

    Gap fading prob –a) Win Rate –b)
    Monday 66.6% 70.8%
    Tuesday 70.0% 74.0%
    Wednesday 71.2% 76.5%
    Thursday 73.4% 73.9%
    Friday 67.4% 72.4%

    (a-Gap fill analysis ES from 19 Oct 1999 to 16 Oct 2009 … http://kurtosistrading.com/blogspot/?p=653
    (b-Win Rate by day of the Week 1998 – 2006 … Scott Andrews, Understanding Gaps

    Mark Austin in his training on fading FTSE gap mentioned this issue. According to Mark, Monday is the weakest day for closing gap. Some significant events can happen over the weekend and also many people get a chance to read and analyze the situation during this time. By Monday morning, they have decided whether to buy or sell and therefore Monday is less likely for gap to close. Friday however is a good day to short the up gap because many share traders would like to take profit and close their position heading to the weekend.

  • Hi Jeff,

    On the baseline system, if you optimize the Stop loss and profit target simultaneously and then plot the results on a 3-D graph, will give a different point of reference for a robust system.

    Using this process, I found that StpLs = 500 and PrfTg = 400, was a bit more robust solution even though the Total Profit suffered somewhat.

    Thanks again for this series.

    Rich S.

    • Rich, those are similar numbers the original author of the system came up with as well. I think my next test will be to look at more dynamic stops and targets based upon the size of the gap.

  • Hi Jeff, thanks for your work. I would be really interested in the application of this filter:

    https://www.rockwelltrading.com/gap-trading/

    I have been using this article for some time now trading Russell, SP500, DOW, NASDAQ futures. There is usually a trade every day between the big 4. The filter would be if any of the following are TRUE:

    1. Yesterday’s candle was a bullish candle (C > O), Today’s open is between yesterday’s open and close. Go Long.

    2. Yesterday’s candle was a bullish candle (C > O), Today’s open is between yesterday’s close and high. Go Short.

    3. Yesterday’s candle was a bearish candle (C < O), Today's open is between yesterday's open and close. Go Short.

    4. Yesterday's candle was a bearish candle (C < O), Today's open is between yesterday's close and low. Go Long.

    These are the highest probability zones of gap filling. The link here is something I just uploaded. This is SPY data since January 1993 showing the 10 possible gap trading zones and their continuous average success of filling the gap to present day. The success rates mean that the gap was filled that same day. The fat black line shows about 70% of all gaps no matter the zone fill the same day. I grouped the trades based on:

    U- : Yesterday was an 'up' day (bullish candle)
    D-: Yesterday was a 'down' day (bearish candle)

    U-HC: Yesterday was an 'up' day, and the open today was between yesterday's High and Close (HC)
    D-CL: Yesterday was a 'down' day, and the open today was between yesterday's Close and Low (CL)

    I grouped the similar categories together with dashed and solid lines so that it is easier to understand what is happening. There is a clear bias to trading the gaps based on zones.

    Maybe a gap trading part 3 article?

    Thanks again for your work.

    • Thanks for posting. I’m planning on incorporating this very filter into a future article. It’s a filter I’m aware of and have tested, many years ago. However, nothing really materialized into a viable trading system. Yet, I think it’s worth revisiting.

  • {"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}

    Learn To Code & Build Strategies
    Using EasyLanguage. 

    >