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.
- 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.
- 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:
- Gap Increments
- 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.
Waiting for out-of-sample test. What about providing Sharpe values?
Hey Alex. Not a big fan of Sharpe values.
Sharpe ratio is too important to neglect. Maybe you like Sortino ratio instead?
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?
I remember Larry Williams to use a gold momentum filter and a bond momentum filter to one of his intraday volatility strategies. Maybe this can help in adding other filters.
http://nightlypatterns.wordpress.com
Hello,
did anyone try to isolate long and short results?
Thank you
Enrico
Good idea. I’ve not done that yet.
I’ve been doing work on that exact idea Enrico, but the results have not been promising so far. I isolated the longs and shorts and tested the target and stop, but 400 is the best target and stop for both longs and shorts.
Thanks Ben. Another idea to test is to break up each gap based upon it’s zone as defined here…
http://www.masterthegap.com/public/Gap_Zone_Map.cfm
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.
I’ve uploaded a copy of the TradeStation Performance Report for the Baseline system. You will find the short trades perform slightly better! This surprised me as I would think the same thing as you did Enrico in regards to the historical up bias.
Thanks for that Jeff; did you use the 200/500 settings for the take profit/stop loss values?
Yes, those are the baseline numbers.
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?
That’s an interesting idea. It would be hard to test the 8:30 open precisely using minute bars. But you could change the session templates so that the session opens one minute earlier (at 8:29), and then run the test at the end of the 8:29 minute bar.
Check at the bottom of the article, I just added some new TradeStation performance reports.
How much interesting are the ‘unbalanced’ results in the ’25 and ’29 tests regarding long and short results. Food for thought.
Thank you Jeff
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,
high five for sharing. How about session hours? Which do you use on the ES for this strategy?
It’s the standard session hours. 8:30AM Central open and 3:15PM Central close.
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.
Sorry, the link I mentioned that never manifested is here: https://ibb.co/mpks0b
Cheers.